最小化使所有素数索引元素成为素数所需的交换
给定一个大小为N的数组arr[] 。任务是找到重新排列数组所需的最小交换次数,以使所有以素数为索引的元素都是素数,如果无法完成任务,则打印“ -1 “
例子:
Input: N = 5, arr[] = {1, 2, 3, 4, 5}
Output: 0
Explanation: All the prime indices {2, 3, 5} (one-based indexing) have prime elements present on them. Therefore, minimum swaps required is 0.
Input: N = 5, arr[] = {2, 7, 8, 5, 13}
Output: 1
Explanation: swap 8 and 5 once, to get all the prime numbers at prime indices.
方法:该任务可以使用埃拉托色尼筛法解决。
- 遍历数组并检查当前索引是否为素数,如果是素数,则检查此索引上存在的元素。
- 观察可以看出,只有当数组中素数的总数大于或等于数组中素数索引的总数时,才有可能实现所需的配置。
- 如果这个条件成立,那么交换的最小数量等于没有素数的素数索引的数量。
下面是上述方法的实现:
C++
#include
using namespace std;
const int mxn = 1e4 + 1;
bool prime[mxn + 1];
// Function to pre-calculate the prime[]
// prime[i] denotes whether
// i is prime or not
void SieveOfEratosthenes()
{
memset(prime, true, sizeof(prime));
for (int p = 2; p * p <= mxn; p++) {
// If prime[p] is not changed,
// then it is a prime
if (prime[p] == true) {
// Update all multiples
// of p greater than or
// equal to the square of it
// numbers which are multiple
// of p and are less than p^2
// are already been marked.
for (int i = p * p; i <= mxn; i += p)
prime[i] = false;
}
}
}
// Function to count minimum number
// of swaps required
int countMin(int arr[], int n)
{
// To count the minimum number of swaps
// required to convert the array into
// perfectly prime
int cMinSwaps = 0;
// To count total number of prime
// indexes in the array
int cPrimeIndices = 0;
// To count the total number of
// prime numbers in the array
int cPrimeNos = 0;
for (int i = 0; i < n; i++) {
// Check whether index
// is prime or not
if (prime[i + 1]) {
cPrimeIndices++;
// Element is not prime
if (!prime[arr[i]])
cMinSwaps++;
else
cPrimeNos++;
}
else if (prime[arr[i]]) {
cPrimeNos++;
}
}
// If the total number of prime numbers
// is greater than or equal to the total
// number of prime indices, then it is
// possible to convert the array into
// perfectly prime
if (cPrimeNos >= cPrimeIndices)
return cMinSwaps;
else
return -1;
}
// Driver Code
int main()
{
// Pre-calculate prime[]
SieveOfEratosthenes();
int n = 5;
int arr[5] = { 2, 7, 8, 5, 13 };
cout << countMin(arr, n);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG {
static boolean prime[] = new boolean[(int)1e4 + 2];
static void SieveOfEratosthenes()
{
// Create a boolean array "prime[0..n]" and
// initialize all entries it as true. A value in
// prime[i] will finally be false if i is Not a
// prime, else true.
for (int i = 0; i < (int)1e4 + 2; i++)
prime[i] = true;
for (int p = 2; p * p < (int)1e4 + 2; p++)
{
// If prime[p] is not changed, then it is a
// prime
if (prime[p] == true)
{
// Update all multiples of p
for (int i = p * p; i < (int)1e4 + 2;
i += p)
prime[i] = false;
}
}
}
// Function to count minimum number
// of swaps required
static int countMin(int[] arr, int n)
{
// To count the minimum number of swaps
// required to convert the array into
// perfectly prime
int cMinSwaps = 0;
// To count total number of prime
// indexes in the array
int cPrimeIndices = 0;
// To count the total number of
// prime numbers in the array
int cPrimeNos = 0;
for (int i = 0; i < n; i++) {
// Check whether index
// is prime or not
if (prime[i + 1]) {
cPrimeIndices++;
// Element is not prime
if (prime[arr[i]] == false)
cMinSwaps++;
else
cPrimeNos++;
}
else if (prime[arr[i]]) {
cPrimeNos++;
}
}
// If the total number of prime numbers
// is greater than or equal to the total
// number of prime indices, then it is
// possible to convert the array into
// perfectly prime
if (cPrimeNos >= cPrimeIndices)
return cMinSwaps;
else
return -1;
}
// Driver Code
public static void main(String[] args)
{
// Pre-calculate prime[]
SieveOfEratosthenes();
int n = 5;
int arr[] = { 2, 7, 8, 5, 13 };
System.out.println(countMin(arr, n));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python program for the above approach
import math
mxn = 10000 + 1
prime = [True for _ in range(mxn + 1)]
# Function to pre-calculate the prime[]
# prime[i] denotes whether
# i is prime or not
def SieveOfEratosthenes():
global prime
for p in range(2, int(math.sqrt(mxn)) + 1):
# If prime[p] is not changed,
# then it is a prime
if (prime[p] == True):
# Update all multiples
# of p greater than or
# equal to the square of it
# numbers which are multiple
# of p and are less than p^2
# are already been marked.
for i in range(p*p, mxn+1, p):
prime[i] = False
# Function to count minimum number
# of swaps required
def countMin(arr, n):
# To count the minimum number of swaps
# required to convert the array into
# perfectly prime
cMinSwaps = 0
# To count total number of prime
# indexes in the array
cPrimeIndices = 0
# To count the total number of
# prime numbers in the array
cPrimeNos = 0
for i in range(0, n):
# Check whether index
# is prime or not
if (prime[i + 1]):
cPrimeIndices += 1
# Element is not prime
if (not prime[arr[i]]):
cMinSwaps += 1
else:
cPrimeNos += 1
elif (prime[arr[i]]):
cPrimeNos += 1
# If the total number of prime numbers
# is greater than or equal to the total
# number of prime indices, then it is
# possible to convert the array into
# perfectly prime
if (cPrimeNos >= cPrimeIndices):
return cMinSwaps
else:
return -1
# Driver Code
if __name__ == "__main__":
# Pre-calculate prime[]
SieveOfEratosthenes()
n = 5
arr = [2, 7, 8, 5, 13]
print(countMin(arr, n))
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
class GFG
{
static bool[] prime = new bool[(int)1e4 + 2];
static void SieveOfEratosthenes()
{
// Create a boolean array "prime[0..n]" and
// initialize all entries it as true. A value in
// prime[i] will finally be false if i is Not a
// prime, else true.
for (int i = 0; i < (int)1e4 + 2; i++)
prime[i] = true;
for (int p = 2; p * p < (int)1e4 + 2; p++) {
// If prime[p] is not changed, then it is a
// prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * p; i < (int)1e4 + 2;
i += p)
prime[i] = false;
}
}
}
// Function to count minimum number
// of swaps required
static int countMin(int[] arr, int n)
{
// To count the minimum number of swaps
// required to convert the array into
// perfectly prime
int cMinSwaps = 0;
// To count total number of prime
// indexes in the array
int cPrimeIndices = 0;
// To count the total number of
// prime numbers in the array
int cPrimeNos = 0;
for (int i = 0; i < n; i++) {
// Check whether index
// is prime or not
if (prime[i + 1]) {
cPrimeIndices++;
// Element is not prime
if (prime[arr[i]] == false)
cMinSwaps++;
else
cPrimeNos++;
}
else if (prime[arr[i]]) {
cPrimeNos++;
}
}
// If the total number of prime numbers
// is greater than or equal to the total
// number of prime indices, then it is
// possible to convert the array into
// perfectly prime
if (cPrimeNos >= cPrimeIndices)
return cMinSwaps;
else
return -1;
}
// Driver Code
public static void Main()
{
// Pre-calculate prime[]
SieveOfEratosthenes();
int n = 5;
int[] arr = { 2, 7, 8, 5, 13 };
Console.Write(countMin(arr, n));
}
}
// This code is contributed by subhammahato348.
Javascript
输出
1
时间复杂度:O(mxn(log(log(mxn)))
辅助空间:O(mxn)