cppAcademy
FROM LEARNING TO COMPETING

Real problems.
Your next challenge.

Explore the Group C Olympiad and Autumn Tournament archive.
Choose a topic. Find a challenge. Build your solution.

274 tasks: 213 from the Municipal, Regional, and National Olympiad rounds (2009–2026), 57 Autumn Tournament tasks (2007–2025), and 4 previously featured problems. 207 tasks have independently written English summaries, analyses, and C++17 solutions; the remaining entries link to Arena. Difficulty labels are learning estimates, not official ratings. Special formats and source clarifications are explained on affected tasks.
GROUP C2022 · MediumGreedy interval matching

Assign Football Outfits

Autumn Tournament (2022)

Submission name: outfit.cpp

Problem summary

Assign every child a different outfit from 1 through N. Child i accepts exactly the outfit numbers in [Li,Ri]. Find any valid assignment or determine that none exists.

Input

N, followed by N interval endpoints Li Ri.

Output

NO, or YES followed by each child’s assigned outfit in input order.

Constraints

1 ≤ N ≤ 1000000; 1 ≤ Li ≤ Ri ≤ N.

Worked example

Original statement sample; constructive output may differ when any valid answer is accepted.

Input

4
1 3
2 4
3 4
2 2

Output

YES
1 3 4 2

Solution analysis

  1. Process outfit numbers from 1 to N. Sort children by their first acceptable outfit. Before assigning number x, insert every not-yet-considered child with Li≤x into a min-heap keyed by Ri.
  2. Assign x to the waiting child whose deadline Ri is smallest. If no child is waiting, nobody can use x. If the smallest deadline is already below x, that child can no longer be satisfied. Either situation makes a perfect assignment impossible. Store results by original child index.
  3. In the sample, outfit 1 goes to child1. At outfit2, child4 has deadline2 and must be chosen before child2. Then child2 receives3 and child3 receives4, producing 1 3 4 2.

Why it works

Suppose some valid completion gives current outfit x to another waiting child while the heap chooses child a with the earliest deadline. In that completion a gets a later outfit y. Swap their outfits: a accepts x, and the other child accepts y because its left endpoint is at most x≤y and its right endpoint is at least a’s right endpoint≥y. Thus the greedy choice preserves feasibility at every step.

Complexity: O(N log N) time for sorting and heap operations; O(N) storage for intervals, the heap and assignment.

Watch out. Keep original child indices after sorting. This is deadline ordering, not ordering by shortest interval. Any valid assignment is allowed; do not require the source’s exact sample permutation.

Commented C++17 solution

An independently written complete program with standard headers.

#include<algorithm>
#include<functional>
#include<iostream>
#include<queue>
#include<utility>
#include<vector>
using namespace std;
struct Child{
    int left;
    int right;
    int index;
};
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin>>n;
    vector<Child>children(n);
    for(int i=0;i<n;i++){
        cin>>children[i].left>>children[i].right;
        children[i].index=i;
    }
    sort(children.begin(),children.end(),[](const Child&a,const Child&b){
        return a.left<b.left;
    });
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>waiting;
    vector<int>assigned(n);
    int next=0;
    for(int outfit=1;outfit<=n;outfit++){
        while(next<n&&children[next].left<=outfit){
            waiting.push({children[next].right,children[next].index});
            next++;
        }
        // The most urgent waiting child must receive this outfit.
        if(waiting.empty()||waiting.top().first<outfit){
            cout<<"NO\n";
            return 0;
        }
        assigned[waiting.top().second]=outfit;
        waiting.pop();
    }
    cout<<"YES\n";
    for(int i=0;i<n;i++){
        if(i>0){
            cout<<' ';
        }
        cout<<assigned[i];
    }
    cout<<'\n';
}

Source: Arena Olimpiici ↗