标签:优先队列
4 8 4 1 3 2 2 1 0 3 5 3 6 4 2 1 7 6 8 3 3 2 0 5 0 3 6 4 5 2 7 7 6 7 6 8 2 2 3 3 3 0 0 2 7 4 3 6 3 2 2 5 8 5 6 5 3 3 1 2 4 6 7 7 6 5 4 3 5
7 1 7 6 5 2 4 3 8 8 4 6 3 1 2 5 8 7 7 3 6 7 1 5 2 8 4 0 1 2 3 4 5 6 7 8
这题可以用集合做,也可以用优先队列做,方法差不多,可以把所有的元素用线段表示,然后从0开始每次找左边界l[i]小于等于当前集合人数的元素,然后把它放进集合(或优先队列)中,然后删掉右边界r[i]不符合条件的元素(即右边界小于当前元素,这里不用考虑左边界了,因为在集合中的元素一定是l[i]<=tot才放进来的,只要考虑右边界就行了)。
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; #define maxn 100060 struct node{ int l,r,idx; }a[maxn],temp; int vis[maxn],c[maxn]; bool operator <(node a,node b){ return a.r>b.r; } priority_queue<node> q; bool cmp(node a,node b){ if(a.l==b.l)return a.r<b.r; return a.l<b.l; } int main() { int n,m,i,j,T,tot,num1; scanf("%d",&T); while(T--) { while(!q.empty())q.pop(); memset(vis,0,sizeof(vis)); scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&a[i].l); a[i].idx=i; } for(i=1;i<=n;i++){ scanf("%d",&a[i].r); } sort(a+1,a+n+1,cmp); if(a[1].l!=0){ printf("0\n"); for(i=1;i<=n;i++){ if(i==n)printf("%d\n",i); else printf("%d ",i); } continue; } tot=0;num1=1; while(1) { while(a[num1].l<=tot && num1<=n){ q.push(a[num1]);num1++; } while(!q.empty()){ temp=q.top(); if(temp.r<tot){ q.pop(); } else break; } if(q.empty())break; temp=q.top(); tot++;c[tot]=temp.idx;vis[temp.idx]=1; q.pop(); } printf("%d\n",tot); for(i=1;i<=n;i++){ if(vis[i])continue; c[++tot]=i; } for(i=1;i<=tot;i++){ if(i==tot)printf("%d\n",c[tot]); else printf("%d ",c[i]); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:优先队列
原文地址:http://blog.csdn.net/kirito_acmer/article/details/47355833