題意:作為主面試官的John想知道當前正在接受面試的同學隊伍中人品值最高的是多少。於是他請你幫忙編寫一個程式來計算。
三種操作:
|
輸入 |
含義 |
| 1 |
C NAME RP_VALUE |
名字為NAME的人品值為RP_VALUE的同學加入面試隊伍。(名字長度不大於5,0 <= RP_VALUE <= 1,000,000,000) |
| 2 |
G |
排在面試隊伍最前面的同學面試結束離開考場。 |
| 3 |
Q |
主面試官John想知道當前正在接受面試的隊伍中人品最高的值是多少。 |
我是用單調隊列來實現的,剛學單調隊列,早就改學習的東西,到現在才學,不說了,單調隊列就是一個單調遞增或者遞減的隊列,元素有兩個關鍵字(下標和索引值),其實你怎麼用就怎麼改,看題目,這題每次查詢是找當前的最大值,而且有出隊的操作,用優先隊列的話肯逾時,每次的出隊維護操作太慢了。每個同學入隊就只要將其入隊,插入到一個前邊比他大的後邊比他小的地方,後面的元素都出隊,這樣每次插入的時間就會小很多,因為隊列不長。而每次同學離開是只要將隊頭下標比他小或等於他的出隊就行了,這樣保證是當前隊伍最大的rp就是隊頭。
| RunID |
Submit Time |
PID |
Language |
Time |
Mem |
Len |
| 408824 |
2011-08-10 14:47:21 |
1894 |
GNU C++ |
1140 ms |
15884KB |
979B |
不知道還能不能最佳化了,感覺有點慢。
#include<cstdio>#include<cmath>#include<iostream>#include<cstring>#include<string>using namespace std;struct queuey{long long key;int flag;}q[1000005];int r,f;int insert(int flag,long long key){while(r>f&&key>q[r].key){r--;}q[++r].key=key;q[r].flag=flag;return 1;}void init(){f=r=0;}int main(){int c,m,k,k1;long long n;char s[100];scanf("%d",&c);getchar();while(c--){k=1;k1=0;while(1){scanf("%s",s);getchar();if(s[0]=='S')continue;if(s[0]=='E'){init();break;}if(s[0]=='C'){scanf("%s",s);scanf("%lld",&n);getchar();insert(k++,n);continue;}if(s[0]=='G'){k1++;while(q[f+1].flag<=k1&&f<r)f++;continue;}if(s[0]=='Q'){if(f==r)printf("-1\n");else{printf("%lld\n",q[f+1].key);}}}}return 0;}