首页 > 代码库 > poj 3190

poj 3190

开始写了两个for,就猜到超时,没想到真的超时,其实也想过队列但发现找不到怎么再找同一个棚里的,早该想到可以再加一个for了,但大佬的方法确实巧妙,已经跪了两个贪心了,伤心

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=50000;
int usd[maxn];
typedef struct note
{
    int a,b,idx;
    bool operator <(const note &p) const//优先队列,输出组大项,所以定义大于运算符,强行输出最小
    {
        if(b==p.b) return a>p.a;
        return b>p.b;//输出的是最小范围
    }
};
note c[maxn];
priority_queue<note> qq;
bool cmp(const note &p,const note &q)
{
    if(p.a==q.a) return p.b<q.b;//不解释,就是个垃圾排序
    return p.a<q.a;
}
int n;
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
        {   scanf("%d%d",&c[i].a,&c[i].b);
            c[i].idx=i;
        }
        sort(c,c+n,cmp);
        qq.push(c[0]);
        int ans=1;
        usd[c[0].idx]=1;
        for(int i=1;i<n;i++)
        {
            if(!qq.empty()&&qq.top().b<c[i].a)
            {
                usd[c[i].idx]=usd[qq.top().idx];//找到进行衔接idx
                qq.pop();
            }
            else
            {
                ans++;
                usd[c[i].idx]=ans;//知道不到就开始个新的棚
            }
            qq.push(c[i]);//最神奇的入队列衔接
        }
        printf("%d\n",ans);
        for(int i=0;i<n;i++)
          printf("%d\n",usd[i]);
          while(!qq.size())
            qq.pop();//记住清空
    }
    return 0;
}

 

poj 3190