HDU 6301 (贪心+优先队列)
题目大意:
求一个长度为n的数列, 给出m个区间,这m个区间各自区间内的数不同
题解:
用优先队列来模拟过程 , 解题思路是想到了 , 可是不知道如何实现 , 果然还须继续努力呀
这道题思路是去掉重复的区间(取最大的区间,用sort+结构体加几个判断条件来实现),用优先队列维护1-n 中没有出现的数(比如给你一个10 3 [2 8] [1 5] [6 10] 的样例,把1 到 10 push进优先队列后,排序后[1 5] 这个区间先,所以先从优先队列里取 1 2 3 4 5,此时队列剩下6 7 8 9 10,下个区间 [2 8] ,我们先把[ 1 2 )这个区间也就是上次剩下的数丢到优先队列里面去。现在优先队列剩下 1 6 7 8 9 10 ,需要从里面取出8 - 5 个数,所以结果现在是1 2 3 4 5 1 6 7 。下个区间[ 6 10 ] ,丢[2 6)这个区间的数进优先队列,也就是 2 3 4 5 这四个数。再从这四个数取 10 - 8 个,所以答案是
1 2 3 4 5 1 6 7 2 3)
参考博客https://blog.csdn.net/YVVVVY/article/details/81186755
#include<stdio.h> #include<algorithm> #include<queue> using namespace std ; int n,m; int ans[100001]; struct no { int u,v; }a[100001]; bool cmp(no a , no b) { if(a.u==b.u) return a.v>b.v; return a.u<b.u; } priority_queue <int,vector<int>,greater<int> > que; int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=0 ; i<m ; i++) { scanf("%d%d",&a[i].u,&a[i].v); } sort(a,a+m,cmp); while(!que.empty()) que.pop(); for(int i=1 ; i<=n ; i++) ans[i]=1; for(int i=1 ; i<=n ; i++) que.push(i); int l,r,Tr,Tl; l=r=0; Tl=a[0].u; Tr=Tl-1; for(int i=0 ; i<m ; i++) { if(a[i].u>l && a[i].v >r) { r=a[i].v; l=a[i].u; for(int j=Tl ; j<l ; j++) que.push(ans[j]); for(int j=Tr+1 ; j<=r ; j++) { ans[j]=que.top(); que.pop(); } Tr=r;Tl=l; } } printf("%d",ans[1]); for(int i = 2;i <= n;i++){ printf(" %d",ans[i]); } puts(""); } }