Open In App

CSES Solutions – Concert Tickets

Last Updated : 21 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

There are N concert tickets available, each with a certain price given as array tickets[]. Then, M customers arrive, one after another. Each customer announces the maximum price they are willing to pay for a ticket given as array customer[], and after this, they will get a ticket with the nearest possible price such that it does not exceed the maximum price.

The task is to print, for each customer, the price that they will pay for their ticket. After this, the ticket cannot be purchased again. If a customer cannot get any ticket, print -1.

Examples:

Input: N = 5, tickets[] = {5, 3, 7, 8, 5}, M = 3, customer[] = {4, 8, 3}
Output:
3
8
-1
Explanation:

  • The first customer is willing to pay a maximum price of 4, so he will purchase the ticket with cost = 3.
  • The second customer is willing to pay a maximum price of 8, so he will purchase the ticket with cost = 8.
  • The third customer is willing to pay a maximum price of 3, but there are no tickets left with cost <= 3, so he won’t be able to purchase any ticket.

Input: N = 4, tickets[] = {1, 1, 1, 1}, M = 4, customer[] = {1, 1, 1, 1}
Output:
1
1
1
1

Approach: To solve the problem, follow the below idea:

The problem can be solved by using upper bound and a frequency map. We can store all the tickets price in a map along with the frequency of each ticket. Now, for every customer[i], we can find the upper bound of customer[i] in the map, this will give us the ticket which has just greater price than what the customer can pay. Since, in a map all the pairs are sorted on the basis of key values, we can get the price by moving to the pair just before the upper bound to get the required ticket price. If there is no pair before it, print -1. Otherwise, decrease the frequency of the ticket by 1.

Step-by-step algorithm:

  • Maintain a map pendingTickets to store the count of each ticket corresponding to its cost.
  • Push the cost of all the tickets along with the count of each ticket.
  • For each customer, find the maximum cost of a ticket which does not exceed the limit of that customer using upper bound.
  • If such a ticket is found, print the cost of ticket, decrease the count of that ticket by 1 and move to the next customer.
  • Otherwise, print -1 for that customer.

Below is the implementation of the algorithm:

C++
#include<bits/stdc++.h>
using namespace std;

void solve(vector<int> &tickets, vector<int> &customer, int N, int M) {

    map<int, int> pendingTickets;
    for (int i = 0; i < N; i++) {
        pendingTickets[tickets[i]] += 1;
    }

    for (int i = 0; i < M; i++) {
        auto it = pendingTickets.upper_bound(customer[i]);
        if (it == pendingTickets.begin()) {
            cout << -1 << "\n";
        }
        else {
            it--;
            cout << it->first << "\n";
            it->second -= 1;
            if (it->second == 0)
                pendingTickets.erase(it);
        }
    }
}

int main() {

    int N = 5, M = 3;
    vector<int> tickets = {5, 3, 7, 8, 5};
    vector<int> customer = {4, 8, 3};

    solve(tickets, customer, N, M);

    return 0;
}
Java
import java.util.*;

public class Main {
    public static void solve(int[] tickets, int[] customer, int N, int M) {
        Map<Integer, Integer> pendingTickets = new HashMap<>();
        for (int i = 0; i < N; i++) {
            pendingTickets.put(tickets[i], pendingTickets.getOrDefault(tickets[i], 0) + 1);
        }

        for (int i = 0; i < M; i++) {
            int currentCustomer = customer[i];
            Map.Entry<Integer, Integer> entry = null;
            for (Map.Entry<Integer, Integer> ticket : pendingTickets.entrySet()) {
                if (ticket.getKey() <= currentCustomer) {
                    entry = ticket;
                } else {
                    break;
                }
            }
            if (entry == null) {
                System.out.println(-1);
            } else {
                System.out.println(entry.getKey());
                int count = entry.getValue() - 1;
                if (count == 0) {
                    pendingTickets.remove(entry.getKey());
                } else {
                    pendingTickets.put(entry.getKey(), count);
                }
            }
        }
    }

    public static void main(String[] args) {
        int N = 5, M = 3;
        int[] tickets = {5, 3, 7, 8, 5};
        int[] customer = {4, 8, 3};

        solve(tickets, customer, N, M);
    }
}
Python
from typing import List
from collections import OrderedDict

def solve(tickets: List[int], customer: List[int], N: int, M: int):
    # Create a dictionary to store the count of each ticket price
    pending_tickets = OrderedDict()
    for i in range(N):
        if tickets[i] in pending_tickets:
            pending_tickets[tickets[i]] += 1
        else:
            pending_tickets[tickets[i]] = 1

    # Sort the dictionary by key
    pending_tickets = OrderedDict(sorted(pending_tickets.items()))

    for i in range(M):
        # Find the ticket price that is just higher than the customer's bid
        it = next((price for price in reversed(pending_tickets) if price <= customer[i]), None)
        if it is None:
            print(-1)
        else:
            print(it)
            pending_tickets[it] -= 1
            if pending_tickets[it] == 0:
                del pending_tickets[it]

# Test the function
N = 5
M = 3
tickets = [5, 3, 7, 8, 5]
customer = [4, 8, 3]

solve(tickets, customer, N, M)
JavaScript
function solve(tickets, customer, N, M) {
    // Create a dictionary to store the count of each ticket price
    let pending_tickets = {};
    for (let i = 0; i < N; i++) {
        if (tickets[i] in pending_tickets) {
            pending_tickets[tickets[i]] += 1;
        } else {
            pending_tickets[tickets[i]] = 1;
        }
    }

    // Sort the dictionary by key
    pending_tickets = Object.fromEntries(
        Object.entries(pending_tickets).sort()
    );

    for (let i = 0; i < M; i++) {
        // Find the ticket price that is just higher than the customer's bid
        let it = null;
        for (let price of Object.keys(pending_tickets).reverse()) {
            if (parseInt(price) <= customer[i]) {
                it = price;
                break;
            }
        }
        if (it === null) {
            console.log(-1);
        } else {
            console.log(it);
            pending_tickets[it] -= 1;
            if (pending_tickets[it] === 0) {
                delete pending_tickets[it];
            }
        }
    }
}

// Test the function
let N = 5;
let M = 3;
let tickets = [5, 3, 7, 8, 5];
let customer = [4, 8, 3];

solve(tickets, customer, N, M);

Output
3
8
-1

Time Complexity: O(N * logN + M * logN), where N is the number of tickets and M is the number of customers.
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads