zoukankan      html  css  js  c++  java
  • CSU1306:Manor(优先队列)

    Description

    Bob有n个正整数,他将这n个整数根据大小划分成两部分。对于小于等于k的整数放在集合A中,其余的放在集合B中。每次他从集合B中取出一个最大的值,将其变成0放入A集合中。然后将A集合中所有的元素都增加a,如果此时A中元素大于k,那么要将该元素放入B中,同时将B集合中剩余的元素都增加b。Bob现在想知道经过m次操作后,B集合中元素的个数。

     

    Input

    有多组测试数据。

    每组测试数据的第一行为4个整数n,k,a,b,n<=100000,k<=10^3,a,b<=100, 含义同上。接下的来的一行有n个数,表示这n个数的初始值(初始值小于等于200)。接下来的一行有一个整数q(q<=100),表示有q个询问。接下来有q行,每行一个正整数m(m<=200),表示第m次操作。

     

    Output

    对于每一个询问m,输出第m次操作前集合B中元素的个数。

     

    Sample Input

    5 100 40 20 1000 250 300 10 25 10 1 2 3 4 5 6 7 8 9 10 4 100 10 10 105 150 25 75 4 1 2 3 4

    Sample Output

    3 2 2 3 3 3 3 3 3 3 2 1 0 1
     
     
    这道题只需要用优先队列存储,而且查询最大200,打表即可
     
    #include <stdio.h>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    struct node
    {
        int l,r;
        bool operator<(node Q) const//先按右边元素取最小,相同则左边取最大
        {
            if (Q.r!=r) return Q.r<r;
            return l<Q.l;
        }
    } mon;
    
    priority_queue<node> Q;
    int ans[2005];
    
    int main()
    {
        int n,k,a,b,x,i,j;
        while(~scanf("%d%d%d%d",&n,&k,&a,&b))
        {
            while(!Q.empty())//清空
                Q.pop();
            int len = 0;
            for(i = 1; i<=n; i++)
            {
                scanf("%d",&x);
                if(x<=k)
                {
                    mon.l = x;//放入A
                    mon.r = 0;//B没有
                    Q.push(mon);
                }
                else
                    len++;//B里的元素
            }
            for(i = 1; i<=205; i++)
            {
                ans[i] = len;//每次操作前B内的个数
                if(len>0)//B里还有
                {
                    mon.l = 0;//往A里放0
                    mon.r = i-1;//第几次
                    Q.push(mon);//压入队列
                    len--;//B个数减1
                }
                while(!Q.empty())//队列不空
                {
                    mon = Q.top();
                    if(mon.l+(i-mon.r)*a<=k)//A内最大的都小于等于k则跳出
                        break;
                    Q.pop();//否则丢入B
                    len++;//B个数加1
                }
            }
            int cnt;
            scanf("%d",&cnt);
            while(cnt--)
            {
                scanf("%d",&x);
                printf("%d
    ",ans[x]);
            }
        }
    
        return 0;
    }
    

  • 相关阅读:
    bzoj3505 数三角形 组合计数
    cogs2057 殉国 扩展欧几里得
    cogs333 荒岛野人 扩展欧几里得
    bzoj1123 BLO tarjan求点双连通分量
    poj3352 road construction tarjan求双连通分量
    cogs1804 联合权值 dp
    cogs2478 简单的最近公共祖先 树形dp
    cogs1493 递推关系 矩阵
    cogs2557 天天爱跑步 LCA
    hdu4738 Caocao's Bridge Tarjan求割边
  • 原文地址:https://www.cnblogs.com/riskyer/p/3294092.html
Copyright © 2011-2022 走看看