标签:
题意:一场演出有N段演奏,每段演奏都有一个音域,有M个演唱家,每个演唱家也分别有自己的音域,而且同一场演出中能演唱最多K次。问是否能够使所有的演奏都能进行,如果能应该怎样分配演唱顺序。
思路:先排个序,把每段演奏以及每个人都按照音域[L,R],R小的优先,相同的情况下,L小的优先。然后对每个人依次操作。每次操作把演奏的R小于等同于该演唱者的R的部分放入multiset中(这里要用到其自动排序和可二分查找的功能),然后二分找到集合中刚好满足演奏的L大于等于演唱者L的位置,然后依次往后找知道没有或者该演唱者次数已够。并把这之中的所有元素删除。
#include<cstdio> #include<cstring> #include<algorithm> #include<set> using namespace std; struct node{ int l,r,k,pos; friend bool operator<(node x,node y){ return x.l<y.l; } } a[100005],b[100005]; bool cmp(node a,node b){ if(a.r==b.r) return a.l<b.l; return a.r<b.r; }; int ans[100005],cnt; int main(){ int n,m; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d%d",&a[i].l,&a[i].r); a[i].pos=i; } scanf("%d",&m); for(int i=0;i<m;i++){ scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].k); b[i].pos=i; } sort(a,a+n,cmp); sort(b,b+m,cmp); multiset<node> s; int cnt=0,cur=0; for(int i=0;i<m;i++){ while(cur<n&&a[cur].r<=b[i].r){ s.insert(a[cur]); cur++; } multiset<node>::iterator e,top; top=s.lower_bound(b[i]); e=s.lower_bound(b[i]); int p=0; while(!s.empty()&&e!=s.end()&&p<b[i].k){ node u=*e; ans[u.pos]=b[i].pos; e++; p++; cnt++; } s.erase(top,e); } if(cnt!=n) printf("NO\n"); else{ printf("YES\n"); for(int i=0;i<n;i++) printf("%d ",ans[i]+1); } return 0; }
标签:
原文地址:http://www.cnblogs.com/N-Psong/p/5778021.html