Open In App

CSES Solutions – Concert Tickets

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:

Below is the implementation of the algorithm:

#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;
}
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);
    }
}
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)
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)

Article Tags :