hdu 5493 Queue(线段树)

来源:互联网 发布:lsd可以在淘宝上买到 编辑:程序博客网 时间:2024/05/01 10:17

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5493

思路:

这题目跟以前做过的一道真的一模一样!!!!0、

是poj上的2828 Buy Tickets,附上链接:http://blog.csdn.net/aaaaacmer/article/details/46932785

套到这道题目里面:线段树记录的就是对于第i个人来说,前面有多少个人比他高。

所以对于第i个 人来说,前面比他的高的人有ki或者是n-ki-i个,也就是说面至少要给这么多人在他的前面空出位置。所以对于第i个人,我就是要插到第ki+1或者是n-ki-i+1的位置上。为了使最后的答案满足,所以我肯定是选择ki和n-ki-i中小的那个。

当然这里需要按照高度从小到大排序,然后一个个放入线段树。

代码:

#include<stdio.h>#include<string.h>#include<algorithm>#define M 1000005using namespace std;int min(int a,int b){    if(a>b)return b;    else return a;}struct node{    int h,k;}p[1000005];struct tree{    int l,r,sum;}tree[M<<2];int ans[M];bool cmp(node a,node b){    return a.h<b.h;}void build(int l,int r,int root){    tree[root].l=l;    tree[root].r=r;    tree[root].sum=r-l+1;    if(l==r)return;    int mid=l+r>>1;    build(l,mid,root<<1);    build(mid+1,r,root<<1|1);}void update(int pos,int root,int z){    tree[root].sum--;    if(tree[root].l==tree[root].r)    {        ans[tree[root].l]=z;        return ;    }    if(pos<=tree[root<<1].sum)update(pos,root<<1,z);    else update(pos-tree[root<<1].sum,root<<1|1,z);}int main(){    int T,i,j,k,N,f,icases;    icases=0;    scanf("%d",&T);    while(T--)    {        icases++;        f=0;        memset(ans,0,sizeof(ans));        scanf("%d",&N);        build(1,N,1);        for(i=1;i<=N;i++)        scanf("%d%d",&p[i].h,&p[i].k);        sort(p+1,p+1+N,cmp);        for(i=1;i<=N;i++)        {            int t=min(p[i].k,N-i-p[i].k);            if(t<0){f=1;break;}        update(t+1,1,p[i].h);        }        printf("Case #%d: ",icases);        if(f)printf("impossible\n");        else         {        for(i=1;i<N;i++)        printf("%d ",ans[i]);        printf("%d\n",ans[N]);    }    }    return 0;}


0 0
原创粉丝点击