先来说说自己对这道题的领悟。
首先,这题使用STL的思路我通过自己的思考能够想到我觉得后面的实现其实不成问题(个人想了很久才想到这样使用STL,第一开始还以为得直接用list呢),然而过程中还是发现了许多问题,下面我就来说说。
通过这道题还是学会了不少,不过即使现在做对了,仍然不知道自己之前这个为什么使用`vector< queue<int> > q;` 会无法编译通过,如果有大神出没,求解答,万分感激。
另外呢,这道题对于时间有要求,如果使用`cin cout 等等` 就会TLE,都换成`scanf printf` 一下子时间消耗就降低了。
还有,这道题题目描述最后说了
Print a blank line after each test case, even after the last one.
可是我并没有注意到,还傻傻的把最后一个空行删掉了,导致在改完TLE之后成了WA。
接下来说说这道题的思路吧,就是因为每个team在大队列中都可以看作一个小队列(大队列中的夹个也就是插入某个小队列的末尾),用关联数组将每个team赋予一个编号,大队列中只存储队列中现有team的编号,利用一个队列的数组来存放每个team的小队列,可以直接通过数组下标来访问这个小队列。
下面就是代码。
#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
using namespace std;
map<int, int> team;//某个人对应这个人所在队伍的编号
//vector< queue<int> > q;//保存每个队伍的小队列
queue<int> q[1010];//保存每个队伍的小队列
queue<int> qt;//在大队列中每个队伍的序号保存在此队列中
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Output.txt","w",stdout);
//ios::sync_with_stdio(false);
int t, kase = 0;
char s[30];
while(scanf("%d", &t) != EOF)
{
if(!t) break;
printf("Scenario #%d\n", ++kase);
team.clear();
for(int i = 0; i < 1000; i++)
while(!q[i].empty()) q[i].pop();
//q.clear();
while(!qt.empty()) qt.pop();
for(int i = 0; i < t; i++)
{
int j, x;
scanf("%d", &j);
while(j--)
{
scanf("%d", &x);
team[x] = i;
}
}
while(scanf("%s", s))
{
if(s[0] == 'S') break;
if(s[0] == 'D')
{
printf("%d\n", q[qt.front()].front());
q[qt.front()].pop();
if( q[qt.front()].empty() ) qt.pop();
}
if(s[0] == 'E')
{
int x;
scanf("%d", &x);
if( q[team[x]].empty() ) qt.push(team[x]);
q[team[x]].push(x);
}
}
printf("\n");
}
return 0;
}
下面这个是之前的错误代码。
#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
using namespace std;
map<int, int> team;//某个人对应这个人所在队伍的编号
//vector< queue<int> > q;//保存每个队伍的小队列
queue<int> q[1010];
queue<int> qt;//在大队列中每个队伍的序号保存在此队列中
int main()
{
freopen("New Text Document.txt","r",stdin);
freopen("Output.txt","w",stdout);
ios::sync_with_stdio(false);
int t, kase = 0;
string s;
while(cin>>t && t)
{
if(kase) cout<<endl;
cout<<"Scenario #"<<++kase<<endl;
team.clear();
//for(int i = 0; i < 1000; i++)
//while(!q[i].empty()) q[i].pop();
//q.clear();
//while(!qt.empty()) qt.pop();
for(int i = 0; i < t; i++)
{
int j, x;
cin>>j;
while(j--)
{
cin>>x;
team[x] = i;
//cout<<team[x]<<endl;
}
}
while(cin>>s)
{
getchar();
//cout<<s<<endl;
if(s[0] == 'S') break;
if(s[0] == 'D')
{
cout<<q[qt.front()].front()<<endl;
q[qt.front()].pop();
if( q[qt.front()].empty() ) qt.pop();
}
if(s[0] == 'E')
{
int x;
cin>>x;
if( q[team[x]].empty() ) qt.push(team[x]);
q[team[x]].push(x);
}
}
}
return 0;
}
下面是刘汝佳标程
// UVa540 Team Queue
// Rujia Liu
#include<cstdio>
#include<queue>
#include<map>
using namespace std;
const int maxt = 1000 + 10;
int main() {
int t, kase = 0;
while(scanf("%d", &t) == 1 && t) {
printf("Scenario #%d\n", ++kase);
// 记录所有人的团队编号
map<int, int> team; // team[x]表示编号为x的人所在的团队编号
for(int i = 0; i < t; i++) {
int n, x;
scanf("%d", &n);
while(n--) { scanf("%d", &x); team[x] = i; }
}
// 模拟
queue<int> q, q2[maxt]; // q是团队的队列,而q2[i]是团队i成员的队列
for(;;) {
int x;
char cmd[10];
scanf("%s", cmd);
if(cmd[0] == 'S') break;
else if(cmd[0] == 'D') {
int t = q.front();
printf("%d\n", q2[t].front()); q2[t].pop();
if(q2[t].empty()) q.pop(); // 团体t全体出队列
}
else if(cmd[0] == 'E') {
scanf("%d", &x);
int t = team[x];
if(q2[t].empty()) q.push(t); // 团队t进入队列
q2[t].push(x);
}
}
printf("\n");
}
return 0;
}