题目链接:http://codeforces.com/contest/496/problem/E
题意:有n场演出,每场演出都有限制的高音和低音。然后m个人给出每个人的极限高音和低音还有出场次数。
最后问能否将每场演出都安排人,最后输出每场演出的出赛人编号,有多种情况就任意输出。
思路挺简单的就将演出和人都按照低音的从小到大拍好序,然后便利演出。将每场演出能符合条件的人数放入set里
然后二分查找最小高音能符合的。
#include <iostream> #include <cstring> #include <algorithm> #include <set> using namespace std; const int M = 1e5 + 10; struct TnT { int l , r , num , pos; }song[M] , person[M] , gg[M]; bool cmp(TnT a , TnT b) { return a.l < b.l; } int ans[M]; set<pair<int , int>> se; int main() { int n , m; scanf("%d" , &n); for(int i = 1 ; i <= n ; i++) { scanf("%d%d" , &song[i].l , &song[i].r); song[i].pos = i , ans[i + 1] = 0; } scanf("%d" , &m); for(int i = 1 ; i <= m ; i++) { scanf("%d%d%d" , &person[i].l , &person[i].r , &person[i].num); person[i].pos = i; gg[i].num = person[i].num; } sort(song + 1 , song + n + 1 , cmp); sort(person + 1 , person + m + 1 , cmp); int temp = 0 , flag = 0; for(int i = 1 ; i <= n ; i++) { while(temp <= m && person[temp].l <= song[i].l) { se.insert(make_pair(person[temp].r , person[temp].pos)); temp++; } set<pair<int , int>>::iterator it; it = se.lower_bound(make_pair(song[i].r , 0)); if(it == se.end()) { flag = 1; break; } else { if(it->first >= song[i].r) { ans[song[i].pos] = it->second; gg[it->second].num--; if(gg[it->second].num == 0) { se.erase(it); } } else { flag = 1; break; } } } if(flag) { printf("NO "); } else { printf("YES "); for(int i = 1 ; i <= n ; i++) { printf("%d " , ans[i]); } printf(" "); } return 0; }