zoukankan      html  css  js  c++  java
  • hdoj5493【树状数组+二分】

    题意:
    给你n个人的高度,
    再给出一个值代表该高度下有前面比他高的 或 后面比他高的人数,
    求满足条件下的最小字典序,
    不行的话输出”impossible”
    思路:
    对于最小字典序,对于每个位置的最小是=min(k,n-i-k);
    先离线排序一下,然后对每个人操作,如果(n-i-k)<0,二分找一下这个位置,然后存一下就好了;

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=1e5+10;
    struct asd{
        int h;
        int k;
    };
    asd q[N];
    bool cmp(asd x,asd y)
    {
        return x.h<y.h;
    }
    int c[N];
    int ans[N];
    int n;
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    int sum(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=c[x];
            x-=lowbit(x);
        }
        return ans;
    }
    void add(int x,int v)
    {
        while(x<=n+7)
        {
            c[x]+=v;
            x+=lowbit(x);
        }
    }
    
    int main()
    {
        int t;
        int cas=1;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%d%d",&q[i].h,&q[i].k);
            sort(q+1,q+n+1,cmp);
            memset(c,0,sizeof(c));
            bool flag=true;
            for(int i=1;i<=n;i++)
            {
                int p=min(q[i].k,n-i-q[i].k);
                if((n-i-q[i].k)<0)
                {
                    flag=false;
                    break;
                }
                p++;
                int left,right;
                left=1;
                right=n;
                while(left<right)
                {
                    int mid=(left+right)/2;
                    if(mid-sum(mid)>=p)
                        right=mid;
                    else
                        left=mid+1;
                }
                add(left,1);
                ans[left]=q[i].h;
            }
            printf("Case #%d:",cas++);
            if(!flag)
                printf(" impossible
    ");
            else
            {
                for(int i=1;i<=n;i++)
                    printf(" %d",ans[i]);
                puts("");
            }
        }
        return 0;
    }
  • 相关阅读:
    C#--C/S--学员管理系统--6--班级和下拉框的数据绑定
    C#--C/S--学员管理系统--5--通用验证类的设计和程序退出
    1046. 最后一块石头的重量
    1029. 两地调度
    1005. K 次取反后最大化的数组和
    944. 删列造序
    874. 模拟行走机器人
    860. 柠檬水找零
    map按值排序
    map按键排序
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934766.html
Copyright © 2011-2022 走看看