题解:P9518 queue
题目大意:
一共有三种情况:start
arrive x``leave x
start
:正在玩游戏的人回到排队的队尾,然后再从正在排队的人中选1-2人开始游戏,如果没有人能进行游戏,则输出Error
,否则输出开始玩游戏的人。
arrive x
:将名为x
的人放入排队队尾,若成功输出OK
,若人已经在队列或正在玩游戏输出Error
。
leave x
:将名为x
的从排队队列中删去,若成功输出OK
,若人已经正在玩游戏输出Error
。
解题思路:
一道模拟,详见代码。
要注意一个坑点:如果只是记录一个人在不在队列里是错误的。如果他退队后进队,应该排在队尾,但是如果只是打个标记则不会判断到这一点。
给一个样例。
输入:
4
arrive A
leave A
arrive A
start
输出:
OK
OK
OK
A
C o d e : Code: Code:(不喜勿喷)
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define itn int
#define N 100100
int n;
queue<string>w,p;//w:正在等待的人的队列,p:正在玩的人的队列
map<string,int>vis,inp,outw;//vis:是否在q或w中,inp:是否在p中,outw:w队列中经过leave而未出队的人数
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n;
while(n--){
string s;
cin>>s;
if(s=="start"){
while(!p.empty()){//将p中的所有元素移动到w的队尾
inp[p.front()]=0;
w.push(p.front());
p.pop();
}
int i=1;
bool f=0;
while(!w.empty()&&i<=2){//将w的队首移动到p中
if(outw[w.front()]>0){//如果这个元素被出对过,那么就把这个元素删去
outw[w.front()]--;
w.pop();
}else{
f=1;
cout<<w.front()<<" ";
inp[w.front()]=1;
p.push(w.front());
w.pop();
i++;
}
}
if(!f){//如果没人,就输出Error
cout<<"Error";
}
cout<<endl;
}else if(s=="arrive"){
string name;
cin>>name;
if(vis[name]==1){//如果已经在队列或正在游玩输出Error
cout<<"Error"<<endl;
}else{//否则入队并输出OK
w.push(name);
vis[name]=1;
cout<<"OK"<<endl;
}
}else if(s=="leave"){
string name;
cin>>name;
if(inp[name]==1||vis[name]==0){//如果在玩游戏或不在队列里输出Error
cout<<"Error"<<endl;
}else{//否则标记这个人需要出队并输出OK
outw[name]++;
vis[name]=0;
cout<<"OK"<<endl;
}
}
}
return 0;
}