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; }