csu 1306 Manor(优先队列)
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1306
1306: Manor
Time Limit: 1 Sec Memory Limit: 128 MB Submit: 125 Solved: 35 [Submit][Status][Web Board]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
【题解】:
优先队列
【code】:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <queue> 6 7 using namespace std; 8 9 int B_cnt,a,i; 10 11 struct Nod 12 { 13 int x; 14 int id; 15 }nd; 16 17 priority_queue<Nod> p_q; 18 19 bool operator<(Nod c,Nod b) 20 { 21 return c.x+(i-c.id)*a<b.x+(i-b.id)*a; 22 /*这种更好 23 if(c.id!=b.id) return c.id>b.id; 24 return c.x<b.x; 25 */ 26 } 27 28 int main() 29 { 30 int n,k,b,q; 31 while(~scanf("%d%d%d%d",&n,&k,&a,&b)) 32 { 33 B_cnt=0; 34 while(!p_q.empty()){p_q.pop();} 35 int x; 36 for(i=0;i<n;i++) 37 { 38 scanf("%d",&x); 39 if(x>k) B_cnt++; 40 else 41 { 42 nd.id = 0; 43 nd.x = x; 44 p_q.push(nd); 45 } 46 } 47 scanf("%d",&q); 48 int maks=0; 49 int qu[220]; 50 for(i=1;i<=q;i++) 51 { 52 scanf("%d",&qu[i]); 53 if(maks<qu[i]) maks=qu[i]; 54 } 55 56 int arr[210]; 57 arr[1]=B_cnt; 58 59 for(i=1;i<=maks;i++) 60 { 61 arr[i]=B_cnt; 62 if(B_cnt>0) 63 { 64 B_cnt--; 65 nd.id = i - 1; 66 nd.x = 0; 67 p_q.push(nd); 68 } 69 while(!p_q.empty()) 70 { 71 Nod temp = p_q.top(); 72 if(temp.x+(i-temp.id)*a<=k) break; 73 p_q.pop(); 74 B_cnt++; 75 } 76 } 77 for(i=1;i<=q;i++) 78 { 79 printf("%d\n",arr[qu[i]]); 80 } 81 } 82 return 0; 83 }