标签:
题目:click here
题意:
邀请k个朋友,每个朋友带有礼物价值不一,m次开门,每次开门让一定人数p(如果门外人数少于p,全都进去)进来,当最后所有人都到了还会再开一次门,让还没进来的人进来,每次都是礼物价值高的人先进。最后给出q个数,表示要输出第ni个进来的人的名字。
分析:
优先队列问题。注意优先队列的比较函数即出队顺序,
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 #include <algorithm> 6 7 using namespace std; 8 const int M = 150005; 9 10 struct Node { // 保存来客信息 11 char name[205]; 12 int val; 13 int id; 14 bool operator < ( const Node x ) const { // 排序注意--在优先队列中的出队顺序 15 if( val == x.val ) return id > x.id; 16 return val < x.val; 17 } 18 }node[M]; 19 struct Time { // 保存开门信息--要排序--给的数据可能不按顺序 20 int t, p; 21 bool operator < ( const Time x ) const { return t < x.t; } 22 }time[M]; 23 24 int k, m, q; 25 char str[M][205]; // 答案 26 27 void solve() { 28 scanf("%d%d%d", &k, &m, &q ); 29 for( int i=1; i<=k; i++ ) { 30 scanf("%s %d", node[i].name, &node[i].val ); 31 node[i].id = i; 32 } 33 for( int i=0; i<m; i++ ) 34 scanf("%d%d", &time[i].t, &time[i].p ); 35 sort( time, time+m ); // 对开门信息排序 36 priority_queue<Node> Q; 37 int order = 0; 38 int last = 0; 39 for( int i=0; i<m; i++ ) { 40 int t, p; t = time[i].t; p = time[i].p; 41 for( int i=last+1; i<=t; i++ ) { 42 Q.push( node[i] ); 43 } 44 for( int i=0; i<p; i++ ) { 45 if( Q.empty() ) break; // 注意当门外的人数比p小时--队列判空直接结束--否则会RE 46 Node nd = Q.top(); Q.pop(); 47 order++; 48 strcpy( str[order], nd.name ); 49 } 50 last = t; 51 } 52 for( int i=last+1; i<=k; i++ ) // m次开门后还要开门一次--门外所有人都进门 53 Q.push( node[i] ); 54 while( !Q.empty() ) { 55 Node nd = Q.top(); Q.pop(); 56 order++; 57 strcpy( str[order], nd.name ); 58 } 59 bool fo = false; // 输出格式 60 for( int i=1; i<=q; i++ ) { 61 int s; scanf("%d", &s ); 62 if( fo ) printf(" %s", str[s] ); 63 else { printf("%s", str[s] ); fo = true; } 64 } 65 printf("\n"); 66 } 67 68 int main() { 69 int t; scanf("%d", &t ); 70 while( t-- ) { 71 solve(); 72 } 73 return 0; 74 }
HDU OJ 5437 Alisha’s Party 2015online A
标签:
原文地址:http://www.cnblogs.com/TaoTaoCome/p/4806837.html