Maximize the size of array by deleting exactly k sub-arrays to make array prime in C++


Given the task is to delete exactly K sub-arrays from a given array Arr[] with N positive elements such that all the remaining elements in the array are prime and the size of the remaining array is maximum.

Input 

Arr[]={4, 3, 3, 4, 3, 4, 3} , K=2

Output 

3

Explanation − K=2, this means only 2 sub-arrays must be deleted.

The sub-arrays deleted are Arr[0] and Arr[3…5] which leaves the array Arr[]={3,3,3} with all the prime elements and the maximum size possible.

Input 

Arr[]={7, 6, 2, 11, 8, 3, 12}, K=2

Output 

3

Explanation − The sub-arrays deleted are Arr[1] and Arr[4…6] and the remaining prime array is Arr[]={7,2,11}.

Approach used in the below program as follows

  • First store all the primes into another array prime[] using the sieve of Eratosthenes by calling the sieve() function

  • In function MaxSize()run a loop from i=0 till i<N and store the index numbers of all the composite numbers into a vector vect of type int.

  • Then run another loop from i=1 till i< vect.size to compute the number of primes that lie between two consecutive composites and store it into another vector diff of type int.

  • Then sort the vector diff using the sort() function.

  • Now run another loop from i=1 to i<diff.size() and compute the prefix sum of this vector which will help us to know how many primes need to be deleted.

  • Using an if statement check for impossible case, that is when K=0 and there are no composites.

  • If K is greater than or equal to the number of composites, then delete all the composites including extra primes and the size of these sub-arrays to be deleted should be 1, in order to get optimal answer

  • If K is less than the number of composites, then we will have to delete those sub-arrays that contain composites and prime sub-arrays should not fall in this category.

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
const int Num = 1e5;
bool prime[Num];
//Sieve of Eratosthenes
void sieve(){
   for (int i = 2; i < Num; i++) {
      if (!prime[i]){
         for (int j = i + i; j < Num; j += i){
            prime[j] = 1;
         }
      }
   }
   prime[1] = 1;
}
int MaxSize(int* arr, int N, int K){
   vector<int> vect, diff;
   //Inserting the indices of composite numbers
   for (int i = 0; i < N; i++){
      if (prime[arr[i]])
         vect.push_back(i);
   }
   /*Computing the number of prime numbers between
   two consecutive composite numbers*/
   for (int i = 1; i < vect.size(); i++){
      diff.push_back(vect[i] - vect[i - 1] - 1);
   }
   //Sorting the diff vector
   sort(diff.begin(), diff.end());
   //Computing the prefix sum of diff vector
   for (int i = 1; i < diff.size(); i++){
      diff[i] += diff[i - 1];
   }
   //Impossible case
   if (K > N || (K == 0 && vect.size())){
      return -1;
   }
   //Deleting sub-arrays of length 1
   else if (vect.size() <= K){
      return (N - K);
   }
   /*Finding the number of primes to be deleted
   when deleting the sub-arrays*/
   else if (vect.size() > K){
      int tt = vect.size() - K;
      int sum = 0;
      sum += diff[tt - 1];
      int res = N - (vect.size() + sum);
      return res;
   }
}
//Main function
int main(){
   sieve();
   int arr[] = { 7, 2, 3, 4, 3, 6, 3, 3 };
   int N = sizeof(arr) / sizeof(arr[0]);
   int K = 2;
   cout<< MaxSize(arr, N, K);
   return 0;
}

Output

If we run the above code we will get the following output −

6

Updated on: 17-Aug-2020

77 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements