Minimum Element for Non-Positive Array in Limited Moves
Last Updated :
27 Dec, 2023
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++
#include <iostream>
using namespace std;
typedef long long int ll;
bool f(ll x, ll max_moves, ll arr[], ll n)
{
ll i = 1;
ll g = 0;
while (i <= n) {
if (arr[i] >= 0) {
if (arr[i] % x == 0) {
g += arr[i] / x;
}
else {
g += (arr[i] / x) + 1;
}
}
else {
g += ( abs (arr[i]) / x) + 1;
}
i++;
}
if (g <= max_moves) {
return true ;
}
return false ;
}
int main()
{
ll n = 4;
ll arr[] = { 0, 4, 3, 2, 7 };
ll max_moves = 5;
ll i = 1;
while (f(i, max_moves, arr, n) == false ) {
i++;
}
cout << i;
return 0;
}
|
Java
import java.util.Scanner;
public class GFG {
static boolean f( long x, long max_moves, long [] arr, int n) {
int i = 1 ;
long g = 0 ;
while (i <= n) {
if (arr[i] >= 0 ) {
if (arr[i] % x == 0 ) {
g += arr[i] / x;
} else {
g += (arr[i] / x) + 1 ;
}
} else {
g += (Math.abs(arr[i]) / x) + 1 ;
}
i++;
}
if (g <= max_moves) {
return true ;
}
return false ;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = 4 ;
long [] arr = { 0 , 4 , 3 , 2 , 7 };
long max_moves = 5 ;
long i = 1 ;
while (!f(i, max_moves, arr, n)) {
i++;
}
System.out.println(i);
}
}
|
Python3
def is_satisfying(x, max_moves, arr):
i = 0
g = 0
while i < len (arr):
if arr[i] > = 0 :
if arr[i] % x = = 0 :
g + = arr[i] / / x
else :
g + = (arr[i] / / x) + 1
else :
g + = ( abs (arr[i]) / / x) + 1
i + = 1
if g < = max_moves:
return True
return False
if __name__ = = "__main__" :
n = 4
arr = [ 0 , 4 , 3 , 2 , 7 ]
max_moves = 5
i = 1
while not is_satisfying(i, max_moves, arr):
i + = 1
print (i)
|
C#
using System;
public class GFG {
static bool f( long x, long max_moves, long [] arr, int n)
{
int i = 1;
long g = 0;
while (i <= n) {
if (arr[i] >= 0) {
if (arr[i] % x == 0) {
g += arr[i] / x;
}
else {
g += (arr[i] / x) + 1;
}
}
else {
g += (Math.Abs(arr[i]) / x) + 1;
}
i++;
}
if (g <= max_moves) {
return true ;
}
return false ;
}
public static void Main()
{
int n = 4;
long [] arr = { 0, 4, 3, 2, 7 };
long max_moves = 5;
long i = 1;
while (!f(i, max_moves, arr, n)) {
i++;
}
Console.WriteLine(i);
}
}
|
Javascript
function f(x, max_moves, arr, n) {
let i = 1;
let g = 0;
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 {
g += Math.floor(Math.abs(arr[i]) / x) + 1;
}
i++;
}
if (g <= max_moves) {
return true ;
}
return false ;
}
let n = 4;
let arr = [0, 4, 3, 2, 7];
let max_moves = 5;
let i = 1;
while (!f(i, max_moves, arr, n)) {
i++;
}
console.log(i);
|
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++
#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 {
moves += ( abs (num) / x) + 1;
}
}
return moves <= max_moves;
}
int findMinimumX(vector< int >& arr, int max_moves)
{
int left = 1;
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;
}
int main()
{
int n = 4;
vector< int > arr = { 0, 4, 3, 2, 7 };
int max_moves = 5;
int result = findMinimumX(arr, max_moves);
cout << result << endl;
return 0;
}
|
Java
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 {
moves += (Math.abs(num) / x) + 1 ;
}
}
return moves <= max_moves;
}
static int findMinimumX( int [] arr, int max_moves)
{
int left = 1 ;
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;
}
public static void main(String[] args)
{
int n = 4 ;
int [] arr = { 0 , 4 , 3 , 2 , 7 };
int max_moves = 5 ;
int result = findMinimumX(arr, max_moves);
System.out.println(result);
}
}
|
Python3
import math
def fun(arr, x, max_moves):
moves = 0
for num in arr:
if num > = 0 :
moves + = num / / x if num % x = = 0 else (num / / x) + 1
else :
moves + = ( abs (num) / / x) + 1
return moves < = max_moves
def findMinimumX(arr, max_moves):
left = 1
right = max (arr)
while left < right:
mid = left + (right - left) / / 2
if fun(arr, mid, max_moves):
right = mid
else :
left = mid + 1
return left
if __name__ = = "__main__" :
n = 4
arr = [ 0 , 4 , 3 , 2 , 7 ]
max_moves = 5
result = findMinimumX(arr, max_moves)
print (result)
|
C#
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);
}
}
|
Javascript
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 {
moves += Math.floor(Math.abs(num) / x) + 1;
}
}
return moves <= max_moves;
}
function findMinimumX(arr, max_moves) {
let left = 1;
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;
}
let arr = [0, 4, 3, 2, 7];
let max_moves = 5;
let result = findMinimumX(arr, max_moves);
console.log(result);
|
Time Complexity: O(n * log(max_element)), where n is array size.
Auxiliary Space: O(1), as we are not using any extra space.
Share your thoughts in the comments
Please Login to comment...