这个题目,我一开始想的是用并查集分配队伍,用于查询,然后再在队列里套队列的方法,但是A不过去,代码如下有点长:
#include<iostream> #include<cstdio> #include<string.h> #include<stack> #include<queue> #include<queue> using namespace std ; #define MAX 1000009 int pre[MAX]; void init(){ for (int i = 0; i <MAX ; i++ ) pre[i]=i; } int Find(int x){ if(x!=pre[x]) pre[x] = Find(pre[x]); return pre[x]; } bool isRight(queue<int>qe,int b){ if(Find(qe.front())==Find(b)) { return true ; } return false ; } void mergetwo(int a, int b) { int fa = Find(a); int fb = Find(b); if(fa!=fb) { pre[fa]=fb; } } int main(){ int NumTeam,teammatesNum ,one,two,temp,index=1; char req[10]; while(scanf("%d",&NumTeam)&&NumTeam) { init(); printf("Scenario #%d\n",index++); while(NumTeam--) { scanf("%d",&teammatesNum); scanf("%d",&one);teammatesNum--; while(teammatesNum--) { scanf("%d",&two); mergetwo(one,two); } } stack< queue<int> > sk ; queue< queue<int> > qe ; queue<int> qtemp ; while(scanf("%s",&req)) { if(strcmp(req,"ENQUEUE")==0) { bool hasmerge= false ; scanf("%d",&temp); if(!qe.empty()&&qtemp.size()==0) { queue<int> qtemp ; qtemp = qe.front(); qe.pop(); } else if(qe.empty()&&qtemp.size()==0) qtemp.push(temp); else { bool res ;hasmerge = isRight(qtemp,temp); if(hasmerge) { qtemp.push(temp); continue; } //此处是用stack进行了一波遍历操作 while(!qe.empty()) { queue<int>tqe; tqe = qe.front(); qe.pop();hasmerge=isRight(tqe,temp); if(hasmerge) tqe.push(temp); sk.push(tqe); } while(!sk.empty()) { qe.push(sk.top()); sk.pop(); } if(!hasmerge) { queue<int> qnew ; qnew.push(temp); qe.push(qnew); } } } else if(strcmp(req,"DEQUEUE")==0&&(qe.size()>0||qtemp.size()>0)) { if(qtemp.size()==0) { qtemp = qe.front(); qe.pop(); } int res = qtemp.front(); qtemp.pop(); printf("%d\n",res); // printf("%d %d %d\n",qtemp.size(),qe.size(),qe.front().size()); }else { break ; } } printf("\n"); } }
过去的代码:
#include <iostream> #include <cstdio> #include <queue> #include <map> #include <cstring> using namespace std; const int maxn = 1001; bool visited[maxn]; int main(){ int cnt = 1; int n; while(scanf("%d",&n)!=EOF,n){ memset(visited,false,sizeof(visited)); queue<int> q[maxn];//每个小队.存储的是每个个体的编号 queue<int> que;//总队列。存储的是每个小队的编号 map<int,int> team;//team[t] = i 。表示的是编号为t的人属于第i个小队 int i; for(i = 0 ; i < n ; ++i){ int m; scanf("%d",&m); while(m--){ int teamnums; scanf("%d",&teamnums); team[teamnums] = i;//为每个编号的人初始化小队... } } printf("Scenario #%d\n",cnt++); string str; while(cin >> str){//不断地输入指令 if(str == "STOP"){//如果当前指令是STOP break;//那么跳出循环 }else if(str == "ENQUEUE"){//如果当前指令是ENQUEUE int t; scanf("%d",&t); q[team[t]].push(t);//将t插入到它所对应的小队中 if(visited[team[t]] == false){//如果该小队还没有被访问过(还没有在总队列中) que.push(team[t]);//将该小队的序号插入到总队列中 visited[team[t]] = true;//将该小队标记为已经访问过 } }else if(str == "DEQUEUE"){//如果当前指令是DEQUEUE printf("%d\n",q[que.front()].front());//那么打印排在总队列排在队首的小队中排在队首的元素 q[que.front()].pop();//将该小队中对手的元素出队 if(q[que.front()].empty() == true){//如果该小队已经为空 visited[que.front()] = false;//那么将该小队重新标记为为访问过 que.pop();//将该小队的编号从总队列中出队.. } } } printf("\n"); } return 0; }