Given the array arr[] and another integer max_moves, Find the minimum possible integer x that must be chosen such that all the elements of the array can be made non-positive in most max_moves operations. In each operation, decrease any element of the array by x.
Examples:
Input: n = 3, arr = [1, 2, 3], max_moves = 4,
Output: 2
Explanation: If the chosen x=1, then we can decrease each element by 1 per operation and it would take a total of 6 moves to make all the elements non-positive which exceeds the max moves allowed
- If the chosen x=2 then :
- In the first operation, we decrease the first element. The array becomes (-1,23]
- In the second operation, we decrease the second element. The array becomes (1.0.3).
- In the third operation, we decrease the third element. The array becomes (-1,0.1]
- In the fourth operation, we decrease the third element again. The array becomes [-1.0,-1)
Hence, x = 2 is the minimum possible integer respecting the given conditions. Thus, the answer is 2.
Input: n = 4, arr = (4, 3, 2, 7], max_moves = 5.
Output: 4
Explanation:
- If we choose x=1, it will take 16 operations to make all the integers non-positive
- If we choose x=2, it will take 9 operations to make all the integers non-positive
- If we choose x=3, it will take operations to make all the integers non-positive
- If we choose x=4, it will take 5 operations to make all the integers non-positive
Hence, x = 4 is the minimum possible decrement that meets the given conditions.
Approach: To solve the problem follow the below idea:
We can observe that when the value of x is small the total operations required are more and when value of x is large total operations required are less. Once you get some valid x then you will always satisfy equation for all values >= x, let’s call it the starting point of success.
Iterate from all values 1 till you reach y and become successful and y will be your answer.
Steps to solve the problem:
- Initialized two variables i = 0 (loop counter) and g = 0 (total number of operations)
- While loop that iterates through each element of the array arr[].
- Inside the while loop, the code checks for two cases positive and negative array element.
- if the current element arr[i] is divisible by the current value of x without any remainder (arr[i] % x == 0).
- If it is divisible, it calculates (arr[i] / x) and adds this value to g. This represents the number of operations needed to divide arr[i] by x.
- If it’s not divisible, it calculates (arr[i] / x) + 1 and adds this value to g. This represents the number of operations needed to divide arr[i] by x and round up to the nearest integer.
- If the array element is negative then take (abs(arr[i]) / x) + 1.
- After processing all elements in the array, the code checks if the total number of operations g is less than or equal to the specified maximum number of operations max_moves.
- If this condition is met, it returns true, indicating that the current value of x satisfies the condition.
- If the condition is not met (i.e., g exceeds max_moves), the function returns false, indicating that the current value of x does not satisfy the condition.
Below is the C++ implementation of the above approach:
// C++ code for the above approach: #include <iostream> using namespace std;
typedef long long int ll;
// Function to check if a given 'x' value // satisfies the condition bool f(ll x, ll max_moves, ll arr[], ll n)
{ ll i = 1;
ll g = 0;
// Iterate through the array to calculate
// the total operations 'g'
while (i <= n) {
if (arr[i] >= 0) {
if (arr[i] % x == 0) {
g += arr[i] / x;
}
else {
g += (arr[i] / x) + 1;
}
}
else {
// For negative elements,
// use ceil(arr[i] / x)
g += ( abs (arr[i]) / x) + 1;
}
i++;
}
// Check if 'g' is within the allowed
// maximum operations 'max_moves'
if (g <= max_moves) {
// 'x' satisfies the condition
return true ;
}
// 'x' does not satisfy the condition
return false ;
} // Drivers code int main()
{ // Specific case: n = 4
ll n = 4;
// Specific case: arr = [4, 3, 2, 7]
ll arr[] = { 0, 4, 3, 2, 7 };
ll max_moves = 5;
ll i = 1;
// Iterate to find the smallest 'x' that
// satisfies the condition
while (f(i, max_moves, arr, n) == false ) {
i++;
}
// Print the smallest 'x' that
// satisfies the condition
cout << i;
return 0;
} |
import java.util.Scanner;
public class GFG {
// Function to check if a given 'x' value satisfies the condition
static boolean f( long x, long max_moves, long [] arr, int n) {
int i = 1 ;
long g = 0 ;
// Iterate through the array to calculate the total operations 'g'
while (i <= n) {
if (arr[i] >= 0 ) {
if (arr[i] % x == 0 ) {
g += arr[i] / x;
} else {
g += (arr[i] / x) + 1 ;
}
} else {
// For negative elements, use ceil(arr[i] / x)
g += (Math.abs(arr[i]) / x) + 1 ;
}
i++;
}
// Check if 'g' is within the allowed maximum operations 'max_moves'
if (g <= max_moves) {
// 'x' satisfies the condition
return true ;
}
// 'x' does not satisfy the condition
return false ;
}
// Main function
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Specific case: n = 4
int n = 4 ;
// Specific case: arr = [4, 3, 2, 7]
long [] arr = { 0 , 4 , 3 , 2 , 7 };
long max_moves = 5 ;
long i = 1 ;
// Iterate to find the smallest 'x' that satisfies the condition
while (!f(i, max_moves, arr, n)) {
i++;
}
// Print the smallest 'x' that satisfies the condition
System.out.println(i);
}
} |
# Python code for the above approach: # Function to check if a given 'x' value # satisfies the condition def is_satisfying(x, max_moves, arr):
i = 0 # Start from the first element (0-indexed)
g = 0
# Iterate through the array to calculate
# the total operations 'g'
while i < len (arr):
if arr[i] > = 0 :
if arr[i] % x = = 0 :
g + = arr[i] / / x
else :
g + = (arr[i] / / x) + 1
else :
# For negative elements,
# use ceil(arr[i] / x)
g + = ( abs (arr[i]) / / x) + 1
i + = 1
# Check if 'g' is within the allowed
# maximum operations 'max_moves'
if g < = max_moves:
# 'x' satisfies the condition
return True
# 'x' does not satisfy the condition
return False
# Driver code if __name__ = = "__main__" :
# Specific case: n = 4
n = 4
# Specific case: arr = [4, 3, 2, 7]
arr = [ 0 , 4 , 3 , 2 , 7 ]
max_moves = 5
i = 1
# Iterate to find the smallest 'x' that
# satisfies the condition
while not is_satisfying(i, max_moves, arr):
i + = 1
# Print the smallest 'x' that satisfies the condition
print (i)
|
// C# code for the above approach using System;
public class GFG {
// Function to check if a given 'x' value satisfies the
// condition
static bool f( long x, long max_moves, long [] arr, int n)
{
int i = 1;
long g = 0;
// Iterate through the array to calculate the total
// operations 'g'
while (i <= n) {
if (arr[i] >= 0) {
if (arr[i] % x == 0) {
g += arr[i] / x;
}
else {
g += (arr[i] / x) + 1;
}
}
else {
// For negative elements, use ceil(arr[i] /
// x)
g += (Math.Abs(arr[i]) / x) + 1;
}
i++;
}
// Check if 'g' is within the allowed maximum
// operations 'max_moves'
if (g <= max_moves) {
// 'x' satisfies the condition
return true ;
}
// 'x' does not satisfy the condition
return false ;
}
// Main function
public static void Main()
{
// Specific case: n = 4
int n = 4;
// Specific case: arr = [4, 3, 2, 7]
long [] arr = { 0, 4, 3, 2, 7 };
long max_moves = 5;
long i = 1;
// Iterate to find the smallest 'x' that satisfies
// the condition
while (!f(i, max_moves, arr, n)) {
i++;
}
// Print the smallest 'x' that satisfies the
// condition
Console.WriteLine(i);
}
} // This code is contributed by ragul21 |
// Javascript code for the above approach // Function to check if a given 'x' value satisfies the condition function f(x, max_moves, arr, n) {
let i = 1;
let g = 0;
// Iterate through the array to calculate the total operations 'g'
while (i <= n) {
if (arr[i] >= 0) {
if (arr[i] % x === 0) {
g += Math.floor(arr[i] / x);
} else {
g += Math.floor(arr[i] / x) + 1;
}
} else {
// For negative elements, use ceil(arr[i] / x)
g += Math.floor(Math.abs(arr[i]) / x) + 1;
}
i++;
}
// Check if 'g' is within the allowed maximum operations 'max_moves'
if (g <= max_moves) {
// 'x' satisfies the condition
return true ;
}
// 'x' does not satisfy the condition
return false ;
} // Driver code // Specific case: n = 4 let n = 4; // Specific case: arr = [4, 3, 2, 7] let arr = [0, 4, 3, 2, 7]; let max_moves = 5; let i = 1; // Iterate to find the smallest 'x' that satisfies the condition while (!f(i, max_moves, arr, n)) {
i++;
} // Print the smallest 'x' that satisfies the condition console.log(i); // This code is contributed by ragul21 |
4
Time Complexity: O(n*max element of array), where n is array size.
Auxiliary Space: O(1), as we are not using any extra space.
Efficient Approach: To solve the problem follow the below idea:
Using Binary search to efficiently find the solution that minimizes the number of moves while finding the maximum allowed moves (max_moves). It uses the ‘fun’ function to check if a given value of x is a valid solution.
- Initialize low to 1, high to the maximum value in arr[], and kk to 0.
- Enter a loop while low is less than or equal to high and kk is 0.
- Calculate the midpoint mid.
- If fun(mid, k, b, n) is true:
- If mid is 1, set answer to 1 and exit the loop and If mid-1 is not a valid solution, set answer to mid and exit, otherwise, update high to mid – 1.
- If fun(mid, max_moves, arr, n) is false, update low to mid + 1.
- Exit the loop when kk becomes 1 or low is greater than high.
- Print the answer, representing the smallest x satisfying the condition.
Below is the implementation of the above idea:
// C++ code for the above approach: #include <algorithm> #include <cmath> #include <iostream> #include <vector> using namespace std;
bool fun(vector< int >& arr, int x, int max_moves)
{ int moves = 0;
for ( int num : arr) {
if (num >= 0) {
if (num % x == 0) {
moves += num / x;
}
else {
moves += (num / x) + 1;
}
}
else {
// For negative elements, use
// ceil(num / x) and subtract
// 1 from moves
moves += ( abs (num) / x) + 1;
}
}
return moves <= max_moves;
} int findMinimumX(vector< int >& arr, int max_moves)
{ // Minimum possible x
int left = 1;
// Maximum possible x
int right = *max_element(arr.begin(), arr.end());
while (left < right) {
int mid = left + (right - left) / 2;
if (fun(arr, mid, max_moves)) {
right = mid;
}
else {
left = mid + 1;
}
}
return left;
} // Drivers code int main()
{ int n = 4;
vector< int > arr = { 0, 4, 3, 2, 7 };
int max_moves = 5;
// Function Call
int result = findMinimumX(arr, max_moves);
cout << result << endl;
return 0;
} |
// Java code for the above approach: import java.util.Arrays;
class GFG {
static boolean fun( int [] arr, int x, int max_moves)
{
int moves = 0 ;
for ( int num : arr) {
if (num >= 0 ) {
if (num % x == 0 ) {
moves += num / x;
}
else {
moves += (num / x) + 1 ;
}
}
else {
// For negative elements, use
// ceil(num / x) and subtract
// 1 from moves
moves += (Math.abs(num) / x) + 1 ;
}
}
return moves <= max_moves;
}
static int findMinimumX( int [] arr, int max_moves)
{
// Minimum possible x
int left = 1 ;
// Maximum possible x
int right = Arrays.stream(arr).max().getAsInt();
while (left < right) {
int mid = left + (right - left) / 2 ;
if (fun(arr, mid, max_moves)) {
right = mid;
}
else {
left = mid + 1 ;
}
}
return left;
}
// Drivers code
public static void main(String[] args)
{
int n = 4 ;
int [] arr = { 0 , 4 , 3 , 2 , 7 };
int max_moves = 5 ;
// Function Call
int result = findMinimumX(arr, max_moves);
System.out.println(result);
}
} // This code is contributed by ragul21 |
import math
# Function to check if the given value of x # satisfies the condition within max_moves def fun(arr, x, max_moves):
moves = 0
for num in arr:
if num > = 0 :
# For non-negative elements, calculate moves
# based on whether num is divisible by x or not
moves + = num / / x if num % x = = 0 else (num / / x) + 1
else :
# For negative elements, use ceil(abs(num) / x) and subtract 1 from moves
moves + = ( abs (num) / / x) + 1
return moves < = max_moves
# Function to find the minimum possible x def findMinimumX(arr, max_moves):
# Minimum possible x
left = 1
# Maximum possible x is the maximum element in the array
right = max (arr)
# Binary search to find the minimum x that satisfies the condition
while left < right:
mid = left + (right - left) / / 2
if fun(arr, mid, max_moves):
right = mid
else :
left = mid + 1
return left
# Drivers code if __name__ = = "__main__" :
n = 4
arr = [ 0 , 4 , 3 , 2 , 7 ]
max_moves = 5
# Function Call
result = findMinimumX(arr, max_moves)
print (result)
|
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{ static bool Fun(List< int > arr, int x, int maxMoves)
{
int moves = 0;
foreach ( int num in arr)
{
if (num >= 0)
{
if (num % x == 0)
{
moves += num / x;
}
else
{
moves += (num / x) + 1;
}
}
else
{
moves += (Math.Abs(num) / x) + 1;
}
}
return moves <= maxMoves;
}
static int FindMinimumX(List< int > arr, int maxMoves)
{
int left = 1;
int right = arr.Max();
while (left < right)
{
int mid = left + (right - left) / 2;
if (Fun(arr, mid, maxMoves))
{
right = mid;
}
else
{
left = mid + 1;
}
}
return left;
}
static void Main()
{
List< int > arr = new List< int > { 0, 4, 3, 2, 7 };
int maxMoves = 5;
int result = FindMinimumX(arr, maxMoves);
Console.WriteLine(result);
}
} |
function fun(arr, x, max_moves) {
let moves = 0;
for (let num of arr) {
if (num >= 0) {
if (num % x === 0) {
moves += num / x;
} else {
moves += Math.floor(num / x) + 1;
}
} else {
// For negative elements, use
// Math.ceil(Math.abs(num) / x) and subtract
// 1 from moves
moves += Math.floor(Math.abs(num) / x) + 1;
}
}
return moves <= max_moves;
} function findMinimumX(arr, max_moves) {
// Minimum possible x
let left = 1;
// Maximum possible x
let right = Math.max(...arr);
while (left < right) {
let mid = left + Math.floor((right - left) / 2);
if (fun(arr, mid, max_moves)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
} // Drivers code let arr = [0, 4, 3, 2, 7]; let max_moves = 5; // Function Call let result = findMinimumX(arr, max_moves); console.log(result); // This code is contributed by Gaurav Arora |
4
Time Complexity: O(n * log(max_element)), where n is array size.
Auxiliary Space: O(1), as we are not using any extra space.