Open In App

Queries to check if sweets of given type can be eaten on given day or not

Last Updated : 20 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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.


 
 

Output: 

Yes No Yes

 

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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads