Given two arrays A[] and B[] (B[i] < A[i]) of size N each and an integer K, the task is to perform the operation of (K – A[i] + B[i]) the maximum number of times such that K becomes 0 or as minimum as possible.
Note: At no moment an operation will be performed such that K becomes negative i.e. the operation cannot be performed if K – A[i] is negative and any index can be selected as many times as possible.
Examples:
Input: N = 3, K = 3, A[] = {2, 3, 4}, B[] = {1, 1, 1}
Output: 2
Explanation: For maximum turns,
Choose A[0] and B[0], so K = 3 – 2 + 1 = 2.
Choose A[0] and B[0], so K = 2 – 2 + 1 = 1.
No other operation is possible. So max turns = 2.Input: N = 2, K = 10, A[] = {5, 4} B[] ={1, 2}
Output: 4
Approach: The problem can be solved based on the following idea:
For performing the operation maximum number of times, always keep picking the indices (say i) so that A[i] – B[i] is minimum.
Say such value is A[i] and B[i], so the maximum performed operations for that index are (K – B[i]) / (A[i] – B[i]) [Here K – B[i] to avoid the last operation where K-A[i] is negative]
Follow the steps mentioned below to implement the idea:
- Create an array (say v) to store the values in the form of (A[i] – B[i], A[i]).
- Sort the array in increasing order on the basis of (A[i] – B[i]).
- Loop from i = 0 to N-1:
- If K – second value of v[i] is not negative then use the above formula to find its contribution (say x).
- Increment the count by x.
- Return the final count as the answer.
Below is the implementation of the above approach.
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to calculate the maximum operations int MakeitMin( int n, int k, int a[], int b[])
{ // Create a vector pair to store the difference
vector<pair< int , int > > v(n);
for ( int i = 0; i < n; i++)
v[i] = { a[i] - b[i], a[i] };
// Sort it accordingly
sort(v.begin(), v.end());
int ans = 0;
for ( int i = 0; i < n; i++) {
// Check if we can perform that turn or not
if (v[i].second > k)
continue ;
// If we can perform, calculate max times
// we can perform that turn
// and add it to ans
int diff
= (k - (v[i].second - v[i].first)) / v[i].first;
ans += diff;
// Reduce the k value
k -= (diff * v[i].first);
}
return ans;
} // Driver Code int main()
{ int N = 2, K = 10;
int A[] = { 5, 4 };
int B[] = { 1, 2 };
cout << MakeitMin(N, K, A, B);
return 0;
} |
// Java code to implement the approach import java.io.*;
import java.util.*;
class GFG {
// Function to calculate the maximum operations
public static int MakeitMin( int n, int k, int a[],
int b[])
{
// Create a array of pairs to store the difference
int v[][] = new int [n][ 2 ];
for ( int i = 0 ; i < n; i++) {
v[i][ 0 ] = a[i] - b[i];
v[i][ 1 ] = a[i];
}
// Sort it accordingly
Arrays.sort(v,
(x, y) -> Integer.compare(x[ 0 ], y[ 0 ]));
int ans = 0 ;
for ( int i = 0 ; i < n; i++) {
// Check if we can perform that turn or not
if (v[i][ 1 ] > k)
continue ;
// If we can perform, calculate max times
// we can perform that turn
// and add it to ans
int diff = (k - (v[i][ 1 ] - v[i][ 0 ])) / v[i][ 0 ];
ans += diff;
// Reduce the k value
k -= (diff * v[i][ 0 ]);
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int N = 2 , K = 10 ;
int A[] = { 5 , 4 };
int B[] = { 1 , 2 };
System.out.print(MakeitMin(N, K, A, B));
}
} // This code is contributed by Rohit Pradhan |
# Python code to implement the approach # Function to calculate the maximum operations def MakeitMin(n, k, a, b):
# Create a vector pair to store the difference
v = [[] for i in range (n)]
for i in range (n):
v[i] = [a[i] - b[i], a[i]]
# Sort it accordingly
v.sort()
ans = 0
for i in range (n):
# Check if we can perform that turn or not
if (v[i][ 1 ] > k):
continue
# If we can perform, calculate max times
# we can perform that turn
# and add it to ans
diff = (k - (v[i][ 1 ] - v[i][ 0 ])) / / v[i][ 0 ]
ans + = diff
# Reduce the k value
k - = (diff * v[i][ 0 ])
return ans
# Driver Code N,K = 2 , 10
A = [ 5 , 4 ]
B = [ 1 , 2 ]
print (MakeitMin(N, K, A, B))
# This code is contributed by shinjanpatra |
// C# code to implement the approach using System;
using System.Collections.Generic;
public class GFG
{ // Function to calculate the maximum operations
public static int MakeitMin( int n, int k, int [] a,
int [] b)
{
// Create a array of pairs to store the difference
int [][] v = new int [n][];
for ( int i = 0; i < n; i++) {
v[i] = new int [] { a[i] - b[i], a[i] };
}
// Sort it accordingly
Array.Sort(v, (x, y) => { return x[0] - y[0]; });
int ans = 0;
for ( int i = 0; i < n; i++) {
// Check if we can perform that turn or not
if (v[i][1] > k)
continue ;
// If we can perform, calculate max times
// we can perform that turn
// and add it to ans
int diff = (k - (v[i][1] - v[i][0])) / v[i][0];
ans += diff;
// Reduce the k value
k -= (diff * v[i][0]);
}
return ans;
}
// Driver Code
public static void Main( string [] args)
{
int N = 2, K = 10;
int [] A = { 5, 4 };
int [] B = { 1, 2 };
// Function Call
Console.WriteLine(MakeitMin(N, K, A, B));
}
} // This code is contributed by phasing17. |
<script> // JavaScript code to implement the approach
// Function to calculate the maximum operations
const MakeitMin = (n, k, a, b) => {
// Create a vector pair to store the difference
let v = new Array(n).fill([]);
for (let i = 0; i < n; i++)
v[i] = [a[i] - b[i], a[i]];
// Sort it accordingly
v.sort();
let ans = 0;
for (let i = 0; i < n; i++) {
// Check if we can perform that turn or not
if (v[i][1] > k)
continue ;
// If we can perform, calculate max times
// we can perform that turn
// and add it to ans
let diff
= (k - (v[i][1] - v[i][0])) / v[i][0];
ans += diff;
// Reduce the k value
k -= (diff * v[i][0]);
}
return ans;
}
// Driver Code
let N = 2, K = 10;
let A = [5, 4];
let B = [1, 2];
document.write(MakeitMin(N, K, A, B));
// This code is contributed by rakeshsahni </script> |
4
Time Complexity: O(N * logN)
Auxiliary Space: O(N)
Another Approach:
- Create a vector of pairs to store the difference (A[i] – B[i]) and the value of A[i] for each index i in the arrays A[] and B[].
- Sort the vector of pairs in non-decreasing order of the difference (A[i] – B[i]). This will ensure that we always pick the indices with minimum difference (A[i] – B[i]) first.
- Initialize a variable ans to 0 to keep track of the maximum number of times we can perform the operation (K – A[i] + B[i]).
- Loop through the vector of pairs from the beginning to the end.
- Check if the value of A[i] is greater than K. If yes, continue to the next iteration of the loop, as we cannot perform the operation (K – A[i] + B[i]) for this index i.
- If the value of A[i] is less than or equal to K, calculate the maximum number of times we can perform the operation for this index i. We can do this by dividing (K – (A[i] – B[i])) by (A[i] – B[i]), and taking the floor of the result.
- Add the maximum number of times we can perform the operation for this index i to the variable ans.
- Reduce the value of K by the maximum number of times we can perform the operation for this index i, multiplied by (A[i] – B[i]).
- Repeat steps 5-8 until we have looped through all the indices in the vector of pairs.
- Return the value of ans as the final answer.
Below is the implementation of above approach:
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std;
// Function to calculate the maximum operations int MakeitMin( int n, int k, int a[], int b[]) {
// Create a priority queue to store the indices with (A[i]-B[i]) priority_queue<pair< int , int >, vector<pair< int , int >>, greater<pair< int , int >>> pq;
for ( int i = 0; i < n; i++) {
pq.push({a[i]-b[i], i}); } int ans = 0;
while (!pq.empty() && k >= 0) {
int idx = pq.top().second;
pq.pop();
// Calculate the maximum number of operations for this index
int max_ops = (k - (a[idx] - b[idx])) / (a[idx] - b[idx]);
// Update the answer and the remaining value of K
ans += max_ops;
k -= max_ops * (a[idx] - b[idx]);
// Push the index back into the priority queue if K is not negative
if (max_ops > 0 && k >= 0) {
pq.push({a[idx]-b[idx], idx});
}
} return ans;
} // Driver Code int main()
{ int N = 2, K = 10;
int A[] = { 5, 4 };
int B[] = { 1, 2 };
cout << MakeitMin(N, K, A, B);
return 0;
} |
import java.util.Comparator;
import java.util.PriorityQueue;
class GFG
{ // Function to calculate the maximum operations
public static int makeItMin( int n, int k, int [] a, int [] b)
{
// Create a priority queue to store the indices with (A[i]-B[i])
PriorityQueue<Pair<Integer, Integer>> pq =
new PriorityQueue<>(Comparator.comparingInt(Pair::getKey));
for ( int i = 0 ; i < n; i++) {
pq.offer( new Pair<>(a[i] - b[i], i));
}
int ans = 0 ;
while (!pq.isEmpty() && k >= 0 ) {
Pair<Integer, Integer> item = pq.poll();
int idx = item.getValue();
// Calculate the maximum number of operations for this index
int max_ops = (k - (a[idx] - b[idx])) / (a[idx] - b[idx]);
// Update the answer and the remaining value of K
ans += max_ops;
k -= max_ops * (a[idx] - b[idx]);
// Push the index back into the priority queue if K is not negative
if (max_ops > 0 && k >= 0 ) {
pq.offer( new Pair<>(a[idx] - b[idx], idx));
}
}
return ans;
}
// Driver Code
public static void main(String[] args) {
int N = 2 , K = 10 ;
int [] A = { 5 , 4 };
int [] B = { 1 , 2 };
System.out.println(makeItMin(N, K, A, B));
}
// Pair class definition
static class Pair<K, V> {
private final K key;
private final V value;
// Constructor
public Pair(K key, V value) {
this .key = key;
this .value = value;
}
// Getters
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
} |
# Python3 code to implement the approach import heapq
# Function to calculate the maximum operations def MakeitMin(n, k, a, b):
# Create a priority queue to store the indices with (A[i]-B[i])
pq = []
for i in range (n):
heapq.heappush(pq, (a[i] - b[i], i))
ans = 0
while pq and k > = 0 :
idx = heapq.heappop(pq)[ 1 ]
# Calculate the maximum number of operations for this index
max_ops = int ((k - (a[idx] - b[idx])) / (a[idx] - b[idx]))
# Update the answer and the remaining value of K
ans + = max_ops
k - = max_ops * (a[idx] - b[idx])
# Push the index back into the priority queue if K is not negative
if max_ops > 0 and k > = 0 :
heapq.heappush(pq, (a[idx] - b[idx], idx))
return ans
# Driver Code if __name__ = = '__main__' :
N = 2
K = 10
A = [ 5 , 4 ]
B = [ 1 , 2 ]
print (MakeitMin(N, K, A, B))
|
using System;
using System.Collections.Generic;
public class Program
{ // Function to calculate the maximum operations
public static int MakeitMin( int n, int k, int [] a, int [] b)
{
// Create a priority queue to store the indices with (A[i]-B[i])
var pq = new PriorityQueue<( int , int )>((x, y) => x.Item1.CompareTo(y.Item1));
for ( int i = 0; i < n; i++)
{
pq.Enqueue((a[i] - b[i], i));
}
int ans = 0;
while (pq.Count > 0 && k >= 0)
{
var item = pq.Dequeue();
int idx = item.Item2;
// Calculate the maximum number of operations for this index
int max_ops = (k - (a[idx] - b[idx])) / (a[idx] - b[idx]);
// Update the answer and the remaining value of K
ans += max_ops;
k -= max_ops * (a[idx] - b[idx]);
// Push the index back into the priority queue if K is not negative
if (max_ops > 0 && k >= 0)
{
pq.Enqueue((a[idx] - b[idx], idx));
}
}
return ans;
}
// Driver Code
public static void Main()
{
int N = 2, K = 10;
int [] A = { 5, 4 };
int [] B = { 1, 2 };
Console.WriteLine(MakeitMin(N, K, A, B));
}
} // Implementation of priority queue in C# public class PriorityQueue<T>
{ private readonly List<T> _data;
private readonly Comparison<T> _comparer;
public PriorityQueue() : this ( null ) { }
public PriorityQueue(Comparison<T> comparer)
{
_data = new List<T>();
_comparer = comparer ?? Comparer<T>.Default.Compare;
}
public void Enqueue(T item)
{
_data.Add(item);
int ci = _data.Count - 1;
while (ci > 0)
{
int pi = (ci - 1) / 2;
if (_comparer(_data[ci], _data[pi]) >= 0) break ;
T tmp = _data[ci]; _data[ci] = _data[pi]; _data[pi] = tmp;
ci = pi;
}
}
public T Dequeue()
{
int li = _data.Count - 1;
T frontItem = _data[0];
_data[0] = _data[li];
_data.RemoveAt(li);
--li;
int ci = 0;
while ( true )
{
int rc = ci * 2 + 2;
int lc = ci * 2 + 1;
if (lc > li) break ;
int minc = (rc > li || _comparer(_data[lc], _data[rc]) < 0) ? lc : rc;
if (_comparer(_data[ci], _data[minc]) <= 0) break ;
T tmp = _data[ci]; _data[ci] = _data[minc]; _data[minc] = tmp;
ci = minc;
}
return frontItem;
}
public int Count { get { return _data.Count; } }
} |
// Function to calculate the maximum operations function MakeitMin(n, k, a, b) {
// Create an array to store the indices with (A[i]-B[i])
const arr = [];
for (let i = 0; i < n; i++) {
arr.push([a[i] - b[i], i]);
}
// sort the array in descending order of diff
arr.sort((a, b) => ((b[0] == a[0]) ? b[1] - a[1] : b[0] - a[0]));
let ans = 0;
while (arr.length && k >= 0) {
const [diff, idx] = arr.pop(); // get the index with maximum diff
// Calculate the maximum number of operations for this index
const max_ops = Math.ceil((k - (a[idx] - b[idx])) / (a[idx] - b[idx]));
// Update the answer and the remaining value of K
ans += max_ops;
k -= max_ops * (a[idx] - b[idx]);
// Push the index back into the array if K is not negative
if (max_ops > 0 && k >= 0) {
arr.push([a[idx]-b[idx], idx]);
// sort the array again after adding an element
arr.sort((a, b) => ((b[0] == a[0]) ? b[1] - a[1] : b[0] - a[0]));
}
}
return ans;
} // Driver Code const N = 2;
const K = 10;
const A = [5, 4];
const B = [1, 2];
console.log(MakeitMin(N, K, A, B));
|
4
Time Complexity: O(N*logN)
Auxiliary Space: O(N)