题目链接:https://vjudge.net/contest/241341#problem/G
题目大意:输入一个N,n次操作。对于第一种操作增加一个病人,告诉病人的t0,st0,r。第二种操作,在时间t,选取一个病情最严重的病人进行医治。病人的严重情况为S(t)=st0+r(t-t0)。如果病人严重情况相同,选r最大的进行医治。(1<=N <=100 000),(0<=r<=100。对于第二种操作输出被治疗的病人。
解题思路:因为r的范围比较小,是0-100,而且对于相同r的病人来说,他们的病情严重程度的相对大小不会因为时间的改变而改变,所以我们可以直接定义100多个优先队列,把r相同的病人都放到同一个优先队列当中,然后队列里存什么呢,因为st0-r*t0是一个定值,所以我们的优先队列就存st0-r*t0,出现‘P’,我们就进队列,只要出现‘A’时,我们就对着100多个优先队列遍历一遍,而且每个优先队列只要取出队首元素+t*r,看它是否会大于等于我们的最大值,记录好所在的优先队列,遍历完之后进行相应的输出,删除对应的队首元素即可。
附上代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cstring>
5 #include<string.h>
6 #include<vector>
7 #include<queue>
8 using namespace std;
9 typedef long long ll;
10 const int inf=0x3f3f3f3f;
11 const int maxn=100005;
12 int n,t;
13 priority_queue<int> q[105];
14
15 void init() //初始化
16 {
17 for(int i=0;i<=100;i++)
18 {
19 while(!q[i].empty())
20 q[i].pop();
21 }
22 }
23
24 int main()
25 {
26 int T;
27 scanf("%d",&T);
28 int kase=0;
29 while(T--)
30 {
31 kase++;
32 init();//清空所有队列元素
33 scanf("%d",&n);
34 printf("Case #%d:
",kase);
35 char c;
36 for(int i=0;i<n;i++)
37 {
38 cin>>c;
39 if(c=='P')
40 {
41 int t0,st0,r;
42 scanf("%d%d%d",&t0,&st0,&r);
43 q[r].push(st0-t0*r); //入队
44 }
45 if(c=='A')
46 {
47 scanf("%d",&t);
48 int st=-inf,k;
49 for(int i=0;i<=100;i++)
50 {
51 if(!q[i].empty())
52 {
53 if(q[i].top()+t*i>=st) //记住要‘=’,因为i变大了,即r变大了
54 {
55 st=q[i].top()+t*i;
56 k=i;
57 }
58 }
59 }
60 q[k].pop();
61 printf("%d %d
",st,k);
62 }
63 }
64 }
65 return 0;
66 }