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("");

    }
}
View Code

 

posted @ 2019-01-15 22:54  shuai_hui  阅读(242)  评论(0编辑  收藏  举报