1、UVALive 3135 Argus
题意:有若干注册信息,每个id每经过一个周期返回一个id信息。求前k个返回信息的id。如果两个信息返回的时间点相同,则小的那个先返回。
思路:优先队列简单应用。

1 #include<iostream>
2 #include<queue>
3 #include<map>
4 #include<cstdio>
5 using namespace std;
6 char s[10];
7 struct nd
8 {
9 int id;
10 int v;
11 nd(int ii=0,int vv=0):id(ii),v(vv){ }
12 friend bool operator<(const nd&a, const nd&b)
13 {
14 if (a.v == b.v) return a.id > b.id;
15 else return a.v > b.v;
16 }
17 };
18 int main()
19 {
20 priority_queue<nd>q;
21 map<int, int>mp;
22 while (~scanf("%s", s))
23 {
24 if (s[0] == '#')break;
25 int id, period;
26 scanf("%d%d", &id, &period);
27 q.push(nd(id, period));
28 mp[id] = period;
29 }
30 int cnt;
31 scanf("%d", &cnt);
32 while (cnt--)
33 {
34 nd u = q.top();
35 q.pop();
36 printf("%d\n", u.id);
37 q.push(nd(u.id, u.v + mp[u.id]));
38 }
39 return 0;
40 }
2、uva 11997 K Smallest Sums
题意:给出k个数组,每个数组有k个元素,现在可以从每个数组各选一个数组成和,共有k^k个。求其前k小的数。
思路:优先队列+多路归并。

1 #include<iostream>
2 #include<queue>
3 #include<functional>
4 #include<algorithm>
5 #include<cstdio>
6 using namespace std;
7 int num[800][800];
8 struct pos
9 {
10 int sum;
11 int id;
12 pos(int ss=0,int ii=0):sum(ss),id(ii){ }
13 friend bool operator<(const pos&a, const pos&b)
14 {
15 return a.sum > b.sum;
16 }
17 };
18 int main()
19 {
20 int k;
21 while (~scanf("%d", &k))
22 {
23 for (int i = 0; i < k; i++)
24 {
25 for (int j = 0; j < k; j++)
26 {
27 scanf("%d", &num[i][j]);
28 }
29 sort(num[i], num[i] + k);
30 }
31 //多路归并
32 for (int i = 1; i < k; i++)
33 {
34 priority_queue<pos>q;
35 for (int j = 0; j < k; j++) q.push(pos(num[0][j] + num[i][0], 0));
36 for (int j = 0; j < k; j++)
37 {
38 pos u = q.top();
39 q.pop();
40 num[0][j] = u.sum;
41 if (u.id + 1 < k) q.push(pos(u.sum - num[i][u.id] + num[i][u.id + 1], u.id + 1));
42 }
43 }
44 for (int i = 0; i < k; i++)
45 {
46 if (i) printf(" ");
47 printf("%d", num[0][i]);
48 }
49 printf("\n");
50 }
51 return 0;
52 }
3、uva 11136 Hoax or what
题意:每天员工都会向箱子里放他们的业绩单,每天结束的时候,老板从中挑出最高和最低的两份,并奖励高业绩的人数目为业绩之差的奖金。问老板要给出多少奖金。
思路:
①两个优先队列。注意一个优先队列的元素可能在另一个优先队列里已经pop。

1 #include<iostream>
2 #include<queue>
3 #include<functional>
4 #include<cstring>
5 using namespace std;
6 const int maxn = 1000100;
7 int numq1[maxn];
8 int numq2[maxn];
9 int main()
10 {
11 int n;
12 while (~scanf("%d", &n))
13 {
14 if (n == 0) break;
15 priority_queue<int, vector<int>, greater<int> >q1;
16 priority_queue<int, vector<int>, less<int> >q2;
17 memset(numq1, 0, sizeof(numq1));
18 memset(numq2, 0, sizeof(numq2));
19
20 long long sum = 0;
21 for (int i = 0; i < n; i++)
22 {
23 int m;
24 scanf("%d", &m);
25 for (int j = 0; j < m; j++)
26 {
27 int v;
28 scanf("%d", &v);
29 q1.push(v);
30 q2.push(v);
31 }
32 int u = q1.top(), v = q2.top();
33 while (numq2[u])
34 {//如果已经在另一个优先队列pop
35 numq2[u]--;
36 q1.pop();
37 u = q1.top();
38 }
39 while (numq1[v])
40 {//如果已经在另一个优先队列pop
41 numq1[v]--;
42 q2.pop();
43 v = q2.top();
44 }
45 sum += v - u;
46 q1.pop(), q2.pop();
47 numq1[u]++, numq2[v]++;
48 }
49 printf("%lld\n", sum);
50 }
51 return 0;
52 }
②可重集multiset

1 #include<iostream>
2 #include<set>
3 using namespace std;
4 int main()
5 {
6 int n;
7 while (~scanf("%d", &n) && n)
8 {
9 long long sum = 0;
10 multiset<int>mt;
11 for (int i = 0; i < n; i++)
12 {
13 int k;
14 scanf("%d", &k);
15 for (int j = 0; j < k; j++)
16 {
17 int v;
18 scanf("%d", &v);
19 mt.insert(v);
20 }
21 sum += *(--mt.end()) - *(mt.begin());
22 mt.erase(mt.begin());
23 mt.erase(--mt.end());
24 }
25 printf("%lld\n", sum);
26 }
27 return 0;
28 }
来源:https://www.cnblogs.com/ivan-count/p/7427508.html
