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++
// 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;
}
Java
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);
}
}
Python3
# 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#
// 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
// 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
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++
// 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
// 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
Python3
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)
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 {
// 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
Time Complexity: O(n * log(max_element)), where n is array size.
Auxiliary Space: O(1), as we are not using any extra space.
Similar Reads
Remove minimum elements from array so that max <= 2 * min
Given an array arr, the task is to remove minimum number of elements such that after their removal, max(arr) <= 2 * min(arr). Examples: Input: arr[] = {4, 5, 3, 8, 3} Output: 1 Remove 8 from the array. Input: arr[] = {1, 2, 3, 4} Output: 1 Remove 1 from the array. Approach: Let us fix each value
6 min read
Find the maximum possible value of last element of the Array
Given a non-negative array arr of size N and an integer M representing the number of moves such that in one move, the value of any one element in the array decreases by one, and the value of its adjacent element on the right increases by one. The task is to find the maximum possible value of the las
7 min read
Maximise minimum element possible in Array after performing given operations
Given an array arr[] of size N. The task is to maximize the minimum value of the array after performing given operations. In an operation, value x can be chosen and A value 3 * x can be subtracted from the arr[i] element.A value x is added to arr[i-1]. andA value of 2 * x can be added to arr[i-2]. F
11 min read
Minimizing Moves to Equalize Array Elements
Given an array arr[] of N integers, For each move, you can select any m (1 <= m <= n) elements from the array and transfer one integer unit from each selected element to one of its adjacent elements at the same time, the task is to find the minimum number of moves needed to make all the intege
7 min read
Minimize moves to next greater element to reach end of Array
Given an array nums[] of size N and a starting index K. In one move from index i we can move to any other index j such that there exists no element in between the indices that is greater than nums[i] and nums[j] > nums[i]. Find the minimum number of moves to reach the last index. Print -1 if it i
14 min read
Minimum increment/decrement to make array non-Increasing
Given an array a, your task is to convert it into a non-increasing form such that we can either increment or decrement the array value by 1 in the minimum changes possible. Examples : Input : a[] = {3, 1, 2, 1}Output : 1Explanation : We can convert the array into 3 1 1 1 by changing 3rd element of a
11 min read
Minimum gcd operations to make all array elements one
Given an array A[] of size N. You can replace any number in the array with the gcd of that element with any of its adjacent elements. Find the minimum number of such operation to make the element of whole array equal to 1. If its not possible print -1. Examples: Input : A[] = {4, 8, 9} Output : 3 Ex
8 min read
Maximize minimum element of an Array using operations
Given an array A[] of N integers and two integers X and Y (X ⤠Y), the task is to find the maximum possible value of the minimum element in an array A[] of N integers by adding X to one element and subtracting Y from another element any number of times, where X ⤠Y. Examples: Input: N= 3, A[] = {1,
8 min read
Minimum value that can't be formed using OR of elements of the Array
Given an array of positive integers arr[]. The task is to Find the minimum positive value which cannot be formed using OR operator on any subset of the array. Examples: Input: arr[] = {2, 3}Output: 1Explanation: Since 1 is missing from array and we cannot make it using OR for any other subset of thi
6 min read
Find minimum moves to bring all elements in one cell of a matrix
Given a matrix mat[][], pair of indices X and Y, the task is to find the number of moves to bring all the non-zero elements of the matrix to the given cell at (X, Y). A move consists of moving an element at any cell to its four directional adjacent cells i.e., left, right, top, bottom. Examples: Inp
7 min read