1. 程式人生 > >POJ 3481 Double Queue

POJ 3481 Double Queue

POJ 3481 Double Queue

(中文版)北大2017大資料研究中心夏令營上機考試 G題 雙佇列

描述

系統A用來維護客戶。每個客戶的id用一個正整數K來表示,當客戶進入系統時用P來表示此使用者的優先度。這個系統有以下請求

0 系統停止執行
1 K P 優先度為P的客戶K進入系統
2 找到優先度最高的客戶,然後此客戶離開系統
3 找到優先度最低的客戶,然後此客戶離開系統

輸入

每行包括一個請求,最後一行包括一個停止請求(程式碼0)。對於新增客戶請求(程式碼1),優先度都是唯一的。客戶的表示K小於106,優先度P小於107,一個客戶可能會被新增多次,每次的優先度可能不同。

輸出

對於每個請求2和3,程式必須輸出一行。這行包括此請求中找到客戶的id。如果系統中沒有客戶,輸出0。

樣例輸入

2
1 20 14
1 30 3
2
1 10 99
3
2
2
0

樣例輸出

0
20
30
10
0

思路

本題說是雙佇列,其實可以用C++的STL中的map來作靈活處理。(其實可以試著用資料結構來處理,準備試一下)。而且英文題目中說的很清楚“You may assume that when there is a request to include a new client in the list (code 1), there is no other request in the list of the same client or with the same priority.”,即插入的K和P的值都沒有重複的,所以可以用map,不存在重複覆蓋的問題。利用了map的性質:第一個關鍵字有序,這樣可以省去排序的麻煩。此題需要scanf()和printf(),若用cin和cout會超時。(找到了用cin和cout而不會超時的辦法——在main()函式最開始的時候加上std::ios::sync_with_stdio(false);
std::cin.tie(0);

這兩行程式碼就OK啦,參考連結cin,cout的加速

原始碼

#include<iostream>
#include<map>
using namespace std;

int main(){
    map<int,int> myMap;
    map<int,int>::iterator iter;//注意map的這種用法
    int n,K,P,sum=0;
    while(scanf("%d",&n)==1 && n!=0){
        if(n==1){
            //本題換作cin,cout超時了
//cin>>K>>P; scanf("%d%d",&K,&P); myMap[P]=K; sum++; } if(n==2){ if(sum==0){ //cout<<0<<endl; printf("0\n"); } else{ iter=myMap.end(); iter--; //cout<<iter->second<<endl; printf("%d\n",iter->second); myMap.erase(iter); sum--; } } if(n==3){ if(sum==0){ //cout<<0<<endl; printf("0\n"); } else{ iter=myMap.begin(); //cout<<iter->second<<endl; printf("%d\n",iter->second); myMap.erase(iter); sum--; } } } return 0; }