Skip to content
Related Articles

Related Articles

Queries to check if sweets of given type can be eaten on given day or not
  • Difficulty Level : Expert
  • Last Updated : 22 Apr, 2021

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 r 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()
{
    // Quantites 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)
    {
 
        // Quantites 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

 
 

Output: 
Yes No Yes

 

Time Complexity: O(N logN)
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :