Minimum prime numbers required to be subtracted to make all array elements equal
Last Updated :
31 Aug, 2021
Given an array arr[] consisting of N positive integers, the task is to find the minimum number of primes numbers required to be subtracted from the array elements to make all array elements equal.
Examples:
Input: arr[]= {7, 10, 4, 5}
Output: 5
Explanation: Following subtraction of primes numbers makes all array elements equal:
- Subtracting 5 from arr[0] modifies arr[] to {2, 10, 4, 5}.
- Subtracting 5 from arr[1] modifies arr[] to {2, 5, 4, 5}.
- Subtracting 3 from arr[1] modifies arr[] to {2, 2, 4, 5}.
- Subtracting 2 from arr[2] modifies arr[] to {2, 2, 2, 5}.
- Subtracting 3 from arr[3] modifies arr[] to {2, 2, 2, 2}.
Therefore, the total numbers of operations required is 5.
Input: arr[]= {10, 17, 37, 43, 50}
Output: 8
Approach: The given problem can be solved using the below observations:
- Every even number greater than 2 is the sum of two prime numbers.
- Every odd number greater than 1, can be represented as the sum of at most 3 prime numbers. Below are the possible cases for the same:
- Case 1: If N is prime.
- Case 2: If (N – 2) is prime. Therefore, 2 numbers required i.e., 2 and N – 2.
- Case 3: If (N – 3) is even, then using Goldbach’s conjecture. (N – 3) can be represented as the sum of two prime numbers.
- Therefore, the idea is to reduce each array element to the minimum value of the array(say M) arr[] and if there exists an element in the array having value (M + 1) then reduce each element to the value (M – 2).
Follow the steps below to solve this problem:
- Initialize an array, say prime[], of size 105, to store at every ith index, whether i is prime number or not using Sieve Of Eratosthenes.
- Find the minimum element present in the array, say M.
- If there exists any element in the array arr[] with value (M + 1), then update M to (M – 2).
- Initialize a variable, say count, to store the number of operations required to make all array elements equal.
- Traverse the given array arr[] and perform the following steps:
- Find the difference between arr[i] and M, say D.
- Update the value of count according to the following values of D:
- If the value of D is a prime number, then increment count by 1.
- If the value of D is an even number, then increment count by 2.
- If the value of D is an odd number, and if (D – 2) is a prime number, then increment count by 2. Otherwise, increment count by 3.
- After completing the above steps, print the value of count as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#define limit 100000
using namespace std;
bool prime[limit + 1];
void sieve()
{
memset (prime, true , sizeof (prime));
for ( int p = 2; p * p <= limit; p++) {
if (prime[p] == true ) {
for ( int i = p * p; i <= limit; i += p)
prime[i] = false ;
}
}
}
int findOperations( int arr[], int n)
{
sieve();
int minm = INT_MAX;
for ( int i = 0; i < n; i++) {
minm = min(minm, arr[i]);
}
int val = minm;
for ( int i = 0; i < n; i++) {
if (arr[i] == minm + 1) {
val = minm - 2;
break ;
}
}
int cnt = 0;
for ( int i = 0; i < n; i++) {
int D = arr[i] - val;
if (D == 0) {
continue ;
}
else if (prime[D] == true ) {
cnt += 1;
}
else if (D % 2 == 0) {
cnt += 2;
}
else {
if (prime[D - 2] == true ) {
cnt += 2;
}
else {
cnt += 3;
}
}
}
return cnt;
}
int main()
{
int arr[] = { 7, 10, 4, 5 };
int N = 4;
cout << findOperations(arr, N);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
static int limit = 100000 ;
static boolean prime[];
static void sieve()
{
prime = new boolean [limit + 1 ];
Arrays.fill(prime, true );
for ( int p = 2 ; p * p <= limit; p++)
{
if (prime[p] == true )
{
for ( int i = p * p; i <= limit; i += p)
prime[i] = false ;
}
}
}
static int findOperations( int arr[], int n)
{
sieve();
int minm = Integer.MAX_VALUE;
for ( int i = 0 ; i < n; i++)
{
minm = Math.min(minm, arr[i]);
}
int val = minm;
for ( int i = 0 ; i < n; i++)
{
if (arr[i] == minm + 1 )
{
val = minm - 2 ;
break ;
}
}
int cnt = 0 ;
for ( int i = 0 ; i < n; i++)
{
int D = arr[i] - val;
if (D == 0 )
{
continue ;
}
else if (prime[D] == true )
{
cnt += 1 ;
}
else if (D % 2 == 0 )
{
cnt += 2 ;
}
else
{
if (prime[D - 2 ] == true )
{
cnt += 2 ;
}
else
{
cnt += 3 ;
}
}
}
return cnt;
}
public static void main(String[] args)
{
int arr[] = { 7 , 10 , 4 , 5 };
int N = 4 ;
System.out.println(findOperations(arr, N));
}
}
|
Python3
import sys
limit = 100000
prime = [ True ] * (limit + 1 )
def sieve():
p = 2
while (p * p < = limit):
if (prime[p] = = True ):
for i in range (p * p, limit, p):
prime[i] = False
p + = 1
def findOperations(arr, n):
sieve()
minm = sys.maxsize
for i in range (n):
minm = min (minm, arr[i])
val = minm
for i in range (n):
if (arr[i] = = minm + 1 ):
val = minm - 2
break
cnt = 0
for i in range (n):
D = arr[i] - val
if (D = = 0 ):
continue
elif (prime[D] = = True ):
cnt + = 1
elif (D % 2 = = 0 ):
cnt + = 2
else :
if (prime[D - 2 ] = = True ):
cnt + = 2
else :
cnt + = 3
return cnt
arr = [ 7 , 10 , 4 , 5 ]
N = 4
print (findOperations(arr, N))
|
C#
using System;
class GFG{
static int limit = 100000;
static bool [] prime;
static void sieve()
{
prime = new bool [limit + 1];
Array.Fill(prime, true );
for ( int p = 2; p * p <= limit; p++)
{
if (prime[p] == true )
{
for ( int i = p * p; i <= limit; i += p)
prime[i] = false ;
}
}
}
static int findOperations( int [] arr, int n)
{
sieve();
int minm = Int32.MaxValue;
for ( int i = 0; i < n; i++)
{
minm = Math.Min(minm, arr[i]);
}
int val = minm;
for ( int i = 0; i < n; i++)
{
if (arr[i] == minm + 1)
{
val = minm - 2;
break ;
}
}
int cnt = 0;
for ( int i = 0; i < n; i++)
{
int D = arr[i] - val;
if (D == 0)
{
continue ;
}
else if (prime[D] == true )
{
cnt += 1;
}
else if (D % 2 == 0)
{
cnt += 2;
}
else
{
if (prime[D - 2] == true )
{
cnt += 2;
}
else
{
cnt += 3;
}
}
}
return cnt;
}
public static void Main( string [] args)
{
int [] arr = { 7, 10, 4, 5 };
int N = 4;
Console.WriteLine(findOperations(arr, N));
}
}
|
Javascript
<script>
var limit = 100000;
var prime = Array(limit + 1).fill( true );
function sieve()
{
for (p = 2; p * p <= limit; p++) {
if (prime[p] == true ) {
for (i = p * p; i <= limit; i += p)
prime[i] = false ;
}
}
}
function findOperations(arr, n)
{
sieve();
var minm = Number.MAX_VALUE;
for (i = 0; i < n; i++) {
minm = Math.min(minm, arr[i]);
}
var val = minm;
for (i = 0; i < n; i++) {
if (arr[i] == minm + 1) {
val = minm - 2;
break ;
}
}
var cnt = 0;
for (i = 0; i < n; i++) {
var D = arr[i] - val;
if (D == 0) {
continue ;
}
else if (prime[D] == true ) {
cnt += 1;
}
else if (D % 2 == 0) {
cnt += 2;
}
else {
if (prime[D - 2] == true ) {
cnt += 2;
}
else {
cnt += 3;
}
}
}
return cnt;
}
var arr = [7, 10, 4, 5];
var N = 4;
document.write(findOperations(arr, N));
</script>
|
Time Complexity: O(N + M * log(log(M))), M is the size of
Auxiliary Space: O(M)
Share your thoughts in the comments
Please Login to comment...