Queries to check if sweets of given type can be eaten on given day or not
Given two arrays A[ ] and B[ ] consisting of N integers, where Ai denotes the quantity of sweets of the ith type and Bi denotes the priority of the ith sweet (higher the value greater is the priority), and an integer K, which denotes maximum number of sweets that can be eaten in a day. Sweets of lower priority cannot be eaten before a sweet of higher priority and only one type of sweet can be eaten in a day. Given an array Q[][] representing queries of the form {Q[i][0], Q[i][1] }, the task for each query is to find whether the sweet of the type Q[i][0] can be eaten on Q[i][1]th day or not. Print “Yes” if possible. Otherwise, print “No”.
Example:
Input: A[] = { 6, 3, 7, 5, 2 }, B[] = { 1, 2, 3, 4, 5 }, K = 3, Q[][] = { {4, 4}, {3, 16}, {2, 7} }
Output: Yes No Yes
Explanation:
Query 1: By eating sweets in the following order, sweets of the fourth type can be eaten on the fourth day.
Day 1: Type 5 -> 2 units
Day 2: Type 4 -> 2 units
Day 3: Type 4 -> 2 units
Day 4: Type 4 -> 1 unit
Query 2: Total sweets of type 5, 4, 3 = 2 + 5 + 7 = 14. Therefore, even after eating one sweet each day won’t leave any sweet of type 3 for Day 16.
Query 3: By eating sweets in the following order, sweets of the 2nd type can be eaten on the 7th day.
Day 1: Type 5 -> 2 units.
Day 2: Type 4 -> 3 units.
Day 3: Type 4 -> 2 units.
Day 4: Type 3 -> 3 units.
Day 5: Type 3 -> 2 units.
Day 6: Type 3 -> 2 units.
Day 7: Type 2 -> 2units.Input: A[] = { 5, 2, 6, 4, 1 }, B[] = { 2, 1, 3, 5, 4 }, K = 4, Q[][] = { {2, 17}, {5, 6} }
Output: Yes No
Approach: The idea to solve this problem is to maintain a window for each sweet-type. This window will basically contain the lower-bound and upper-bound of days, within which a sweet of that type can be eaten using the following conditions:
- For the lower-bound of the window, consider the minimum days required to complete all the sweets of higher priority, i.e. subtract minimum(K, remaining amount) from a sweet of a type of each day.
- For the upper-bound of the window, consider the maximum days to complete all the sweets of higher priority, i.e. sum of all total number of sweets of higher priority.
Once the window is prepared for each type, simply check for each query whether the given day lies within the window or not. Follow the steps below to solve the problem:
Steps:
- Maintain a container, say a vector of pairs v to store priority and quantity of every sweet-type.
- Sort the vector of pairs in decreasing order of priority.
- Initialize two variables, say lowerbound and upperbound, to store the window limits for each sweet-type.
- Traverse the vector v and perform the following steps:
- Calculate the maximum and minimum number of days required to eat sweet of the ith type as max_days = A[i] and min_days = ceil(A[i] / K).
- Update upperbound += max_days.
- Store the window { lowerbound, upperbound} for the current sweet-type.
- Update lowerbound += min_days.
- Once the above steps are completed, traverse the array Q[][] and for each query check if the given day of a given sweet-type falls within the window { lowerbound, upperbound} of that sweet-type or not. If found to be true, print “Yes”. Otherwise, print “No”.
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Function to find queries to check // if a sweet of given type can be // eaten on a given day or not void sweetTypeOnGivenDay( int a[], int b[], int n, int k, vector<pair< int , int > >& q) { // Stores pairs {priority, quantity} // of each sweet-type vector<pair< int , pair< int , int > > > v; for ( int i = 0; i < n; i++) v.push_back({ b[i], { a[i], i + 1 } }); // Sorting the order of sweets in // decreasing order of their priority sort(v.begin(), v.end(), greater<pair< int , pair< int , int > > >()); // Stores the window {min_days, max_days} // for each sweet-type map< int , pair< int , int > > mp; // Variables to calculate the windows int lowerbound = 0, upperbound = 0; // Traverse the array for ( int i = 0; i < n; i++) { // Calculating maximum and minimum // number of days required to complete // the sweets of the current type int maxi_days = v[i].second.first; int mini_days = v[i].second.first / k; if (v[i].second.first % k != 0) mini_days++; // Creating the window and storing it upperbound += maxi_days; mp[v[i].second.second] = { lowerbound, upperbound }; lowerbound += mini_days; } // Traversing the queries for ( int i = 0; i < q.size(); i++) { // x: Type of sweet, y: Day int x = q[i].first, y = q[i].second; // Find the window for the // sweet of type x int e = mp[x].first; int f = mp[x].second; // If the given day lies // within the window if (y >= e && y <= f) cout << "Yes" << " " ; else cout << "No" << " " ; } } // Driver Code int main() { // Quantities of sweets of each type int A[] = { 6, 3, 7, 5, 2 }; // Priorites of each type sweet int B[] = { 1, 2, 3, 4, 5 }; // Maximum sweet of one type // that can be eaten on a day int K = 3; // Queries vector<pair< int , int > > Queries = { { 4, 4 }, { 3, 16 }, { 2, 7 } }; // Calculating number of types int n = sizeof (A) / sizeof (A[0]); sweetTypeOnGivenDay(A, B, n, K, Queries); } |
Java
// Java implementation of the above approach import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Map; class GFG { static class Pair<K, V> { K first; V second; public Pair(K first, V second) { this .first = first; this .second = second; } public static <K, V> Pair<K, V> of(K first, V second) { return new Pair<>(first, second); } } // Function to find queries to check // if a sweet of given type can be // eaten on a given day or not static void sweetTypeOnGivenDay( int a[], int b[], int n, int k, ArrayList<Pair<Integer, Integer>> q) { // Stores pairs {priority, quantity} // of each sweet-type ArrayList<Pair<Integer, Pair<Integer, Integer>>> v = new ArrayList<>(); for ( int i = 0 ; i < n; i++) v.add(Pair.of(b[i], Pair.of(a[i], i + 1 ))); // Sorting the order of sweets in // decreasing order of their priority Collections.sort(v, new Comparator<Pair<Integer, Pair<Integer, Integer>>>() { @Override public int compare(Pair<Integer, Pair<Integer, Integer>> a, Pair<Integer, Pair<Integer, Integer>> b) { if (a.first == b.first) { if (a.second.first == b.second.first) { return b.second.second - a.second.second; } return b.second.first - a.second.first; } return b.first - a.first; } }); // Stores the window {min_days, max_days} // for each sweet-type Map<Integer, Pair<Integer, Integer>> mp = new HashMap<>(); // Variables to calculate the windows int lowerbound = 0 , upperbound = 0 ; // Traverse the array for ( int i = 0 ; i < n; i++) { // Calculating maximum and minimum // number of days required to complete // the sweets of the current type int maxi_days = v.get(i).second.first; int mini_days = v.get(i).second.first / k; if (v.get(i).second.first % k != 0 ) mini_days++; // Creating the window and storing it upperbound += maxi_days; mp.put(v.get(i).second.second, Pair.of(lowerbound, upperbound)); lowerbound += mini_days; } // Traversing the queries for ( int i = 0 ; i < q.size(); i++) { // x: Type of sweet, y: Day int x = q.get(i).first, y = q.get(i).second; // Find the window for the // sweet of type x int e = mp.get(x).first; int f = mp.get(x).second; // If the given day lies // within the window if (y >= e && y <= f) System.out.println( "Yes " ); else System.out.println( "No " ); } } // Driver Code public static void main(String[] args) { // Quantities of sweets of each type int A[] = { 6 , 3 , 7 , 5 , 2 }; // Priorites of each type sweet int B[] = { 1 , 2 , 3 , 4 , 5 }; // Maximum sweet of one type // that can be eaten on a day int K = 3 ; // Queries ArrayList<Pair<Integer, Integer>> Queries = new ArrayList<>( Arrays.asList(Pair.of( 4 , 4 ), Pair.of( 3 , 16 ), Pair.of( 2 , 7 ))); // Calculating number of types int n = A.length; sweetTypeOnGivenDay(A, B, n, K, Queries); } } // This code is contributed by sanjeev2552 |
Python3
# Python3 program for the above approach # Function to find queries to check # if a sweet of given type can be # eaten on a given day or not def sweetTypeOnGivenDay(a, b, n, k, q): # Stores pairs priority, quantity # of each sweet-type v = [ [ b[i], [ a[i], i + 1 ] ] for i in range (n)] # Sorting the order of sweets in # decreasing order of their priority v.sort(reverse = True ) # Stores the window min_days, max_days # for each sweet-type mp = {}; # Variables to calculate the windows lowerbound = 0 upperbound = 0 ; # Traverse the array for i in range (n): # Calculating maximum and minimum # number of days required to complete # the sweets of the current type maxi_days = v[i][ 1 ][ 0 ]; mini_days = int (v[i][ 1 ][ 0 ] / k); if (v[i][ 1 ][ 0 ] % k ! = 0 ): mini_days + = 1 ; # Creating the window and storing it upperbound + = maxi_days; mp[v[i][ 1 ][ 1 ]] = [ lowerbound, upperbound ]; lowerbound + = mini_days; # Traversing the queries for i in range ( len (q)): # x: Type of sweet, y: Day x = q[i][ 0 ] y = q[i][ 1 ]; # Find the window for the # sweet of type x e = mp[x][ 0 ]; f = mp[x][ 1 ]; # If the given day lies # within the window if (y > = e and y < = f): print ( "Yes " ); else : print ( "No " ); # Driver Code # Quantities of sweets of each type A = [ 6 , 3 , 7 , 5 , 2 ]; # Priorites of each type sweet B = [ 1 , 2 , 3 , 4 , 5 ]; # Maximum sweet of one type # that can be eaten on a day K = 3 ; # Queries Queries = [[ 4 , 4 ], [ 3 , 16 ], [ 2 , 7 ]]; # Calculating number of types n = len (A) sweetTypeOnGivenDay(A, B, n, K, Queries); # This code is contributed by phasing17. |
C#
// C# implementation of the above approach using System; using System.Linq; using System.Collections.Generic; class GFG { // Function to find queries to check // if a sweet of given type can be // eaten on a given day or not static void sweetTypeOnGivenDay( int [] a, int [] b, int n, int k, List<Tuple< int , int >> q) { // Stores Tuples {priority, quantity} // of each sweet-type List<Tuple< int , Tuple< int , int >>> v = new List<Tuple< int , Tuple< int , int >>>(); for ( int i = 0; i < n; i++) v.Add(Tuple.Create(b[i], Tuple.Create(a[i], i + 1))); // Sorting the order of sweets in // decreasing order of their priority v = v.OrderBy(a => a.Item1).ThenBy(a => a.Item2.Item1).ThenBy(a => a.Item2.Item2).ToList(); v.Reverse(); // Stores the window {min_days, max_days} // for each sweet-type Dictionary< int , Tuple< int , int >> mp = new Dictionary< int , Tuple< int , int >>(); // Variables to calculate the windows int lowerbound = 0, upperbound = 0; // Traverse the array for ( int i = 0; i < n; i++) { // Calculating maximum and minimum // number of days required to complete // the sweets of the current type int maxi_days = v[i].Item2.Item1; int mini_days = v[i].Item2.Item1 / k; if (v[i].Item2.Item1 % k != 0) mini_days++; // Creating the window and storing it upperbound += maxi_days; mp[v[i].Item2.Item2] = Tuple.Create(lowerbound, upperbound); lowerbound += mini_days; } // Traversing the queries for ( int i = 0; i < q.Count; i++) { // x: Type of sweet, y: Day int x = q[i].Item1, y = q[i].Item2; // Find the window for the // sweet of type x int e = mp[x].Item1; int f = mp[x].Item2; // If the given day lies // within the window if (y >= e && y <= f) Console.Write( "Yes " ); else Console.Write( "No " ); } } // Driver Code public static void Main( string [] args) { // Quantities of sweets of each type int [] A = { 6, 3, 7, 5, 2 }; // Priorites of each type sweet int [] B = { 1, 2, 3, 4, 5 }; // Maximum sweet of one type // that can be eaten on a day int K = 3; // Queries List<Tuple< int , int >> Queries = new List<Tuple< int , int >>{ Tuple.Create(4, 4), Tuple.Create(3, 16), Tuple.Create(2, 7)}; // Calculating number of types int n = A.Length; sweetTypeOnGivenDay(A, B, n, K, Queries); } } // This code is contributed by phasing17 |
Javascript
// JS program for the above approach // Function to find queries to check // if a sweet of given type can be // eaten on a given day or not function sweetTypeOnGivenDay(a, b, n, k, q) { // Stores pairs {priority, quantity} // of each sweet-type let v = []; for ( var i = 0; i < n; i++) v.push([ b[i], [ a[i], i + 1 ] ]); // Sorting the order of sweets in // decreasing order of their priority v.sort( function (a, b) { if (a[0] == b[0]) { if (a[1][0] == b[1][0]) return - a[1][1] + b[1][1]; return - a[1][0] + b[1][0]; } return - a[0] + b[0]; }) // Stores the window {min_days, max_days} // for each sweet-type let mp = {}; // Variables to calculate the windows let lowerbound = 0, upperbound = 0; // Traverse the array for (let i = 0; i < n; i++) { // Calculating maximum and minimum // number of days required to complete // the sweets of the current type let maxi_days = v[i][1][0]; let mini_days = Math.floor(v[i][1][0] / k); if (v[i][1][0] % k != 0) mini_days++; // Creating the window and storing it upperbound += maxi_days; mp[v[i][1][1]] = [ lowerbound, upperbound ]; lowerbound += mini_days; } // Traversing the queries for (let i = 0; i < q.length; i++) { // x: Type of sweet, y: Day let x = q[i][0] let y = q[i][1]; // Find the window for the // sweet of type x let e = mp[x][0]; let f = mp[x][1]; // If the given day lies // within the window if (y >= e && y <= f) process.stdout.write( "Yes " ); else process.stdout.write( "No " ); } } // Driver Code // Quantities of sweets of each type let A = [ 6, 3, 7, 5, 2 ]; // Priorites of each type sweet let B = [ 1, 2, 3, 4, 5 ]; // Maximum sweet of one type // that can be eaten on a day let K = 3; // Queries let Queries = [[ 4, 4 ], [ 3, 16 ], [ 2, 7 ]]; // Calculating number of types let n = A.length sweetTypeOnGivenDay(A, B, n, K, Queries); // This code is contributed by phasing17. |
Yes No Yes
Time Complexity: O(N logN)
Auxiliary Space: O(N)
Please Login to comment...