Bootstrap

[ 数据结构 ] DS线性表综合练习--组队列

问题 Q: DS线性表综合练习--组队列

时间限制: 1 Sec   内存限制: 128 MB
提交: 1016   解决: 219
[ 提交][ 状态][ 讨论版]

题目描述

组队列是队列结构中一种常见的队列结构,在很多地方有着广泛应用。组队列是是指队列内的元素分组聚集在一起。组队列包含两种命令:

1、 ENQUEUE,表示当有新的元素进入队列,首先会检索是否有同一组的元素已经存在,如果有,则新元素排在同组的最后,如果没有则插入队列末尾。

2、 DEQUEUE,表示队列头元素出队

3、 STOP,停止操作

建议使用C++自带的队列对象queue,编程更方便

输入

第1行输入一个t(t<=10),表示1个队列中有多少个组

第2行输入一个第1组的元素个数和数值

第3行输入一个第2组的元素个数和数值

以此类推输入完t组之后,开始输入多个操作命令(<200),例如输入ENQUEUE 100,表示把元素100插入队列

最后输入STOP,表示输入命令结束

输出

DEQUEUE出队的元素

样例输入

2
3 101 102 103
3 201 202 203
ENQUEUE 101
ENQUEUE 201
ENQUEUE 102
ENQUEUE 202
ENQUEUE 103
ENQUEUE 203
DEQUEUE
DEQUEUE
DEQUEUE
STOP

样例输出

101 102 103

提示

/*
  做这道题的心路非常复杂...
  
  看到题目时的第一反应:哇!~这题我好像做过,我对题目还有印象,跟这个题目基本上一模一样!~
  
  于是立刻就开始写了,兴高采烈地敲完,以为可以直接 AC 的,结果错误 50%,后来我百思不得其解,为什么会错误 50% 呢?突然想起这题我不是做过嘛,我就去翻书了,然而,我发现...我连它在书上的哪里都忘了...
  
  后来还是请教了同学,才知道我自己究竟是错在哪...同时,后来的后来,当昨天的实验已经截至以后,我又翻开《入门经典》准备做题时,才发现,这分明不就是 UVA - 540 Team Queue 吗?我当时还写清楚了我的思路啊!为什么现在忘得如此彻底了呢?
  ( http://blog.csdn.net/mofushaohua_ln/article/details/77727207 )
  
  
  可是虽然找到了,我并不高兴啊!一点也不高兴,恰恰相反,我觉得自己的内疚和自责到达了峰值...毕竟,这不是暑假时才做过的吗?这也才2个月不到,我怎么就把作法,和题目在书上哪个位置,都忘记得一干二净了呢?
  
  这个故事告诉了我两个道理:
  1. 不要以为自己会了就不敲了,我以为的我会了,和我真正的会,是完全不同的。比如这题吧,还没WA之前,我第一眼就觉得一定会做,AC也就是几分钟的事情。
  
  可是,不是这样子的...一动手重敲时,很多错误才会真正暴露出来。之前做的对,不代表现在就能做对。一看就会,不代表真的就能一次AC...
  
  这让我想起,有些 ACMer 中的大牛,给建议时说:水题就不用做了,浪费时间。可能我还没有到大牛那样的水平吧,听师兄们说,很多大牛时 5min 敲完一题,不用调试直接 submit,而且一般都是能直接 AC 的...我还没有这样的境界,我觉得如果 15min 内不能从头到尾重敲并 AC,那这道题对我就不是水题,而是有必要做的练习题。可能,我和大牛们的实力差距太大了,即便是他们认为的水题,我觉得我还是应该好好做的
  
  2.
  好记性不如烂笔头啊!要时时记录总结。当然最重要的是,一定要及时复习,某种意义上说,复习甚至比学新知识更加重要...我觉得这一点上,我总结做得还马马虎虎吧,但是复习这方面,真的做得相当糟糕 T^T ,从今天起慢慢改正吧!~

*/


// WA 50%的版本
/*
  这个版本的错误就在于,我们给定的几个 group,其实它们是平级的,没有相互顺序
  
  换句话说就是,我们只是给定队伍之间队员的关系,并不是说,先给这个group,这个group在队列中,就一定排在更前的位置,并不是这样子的!
  
  比如这题的测试数据,虽然他给了两个 group,但是,并不是我们先给的group(3 101 102 103),就一定排在整个队伍的前面
  
  如果我们后给的那个group(3 201 202 203),里面的成员先入队,那么后一个队伍就排在前一个队伍前面了
  
  我 WA 的原因就是没考虑到这个问题,现在发现,自己考虑问题还是不够细致和周全,下次一定要注意!!!
*/
#include <iostream>
#include <queue>
#include <string>
#include <map>
#define rep(i, n) for ( int i = 0; i < (n); i++ )
using namespace std;
int t; // group 的总数 
queue<int> q[10];
map<int, int> group; //建立数字和组号的一一对应关系

int isinserted (int n)
{
	rep(i, t)
	{
		if ( q[i].empty() || group[q[i].front()] == group[n] )
		return i;
	}
	return -1;
}

void solve()
{
	int first = 1;
	queue<int> empty[10];
	swap(q, empty);
	
	group.clear();
	int n, num;
	cin >> t;
	
	rep(i, t)
	{
		cin >> n; //该组有n个人,每个人的组号都标为 i 
		rep(j, n)
		{
			cin >> num;
			group[num] = i;
		}
	} 
	
	string str;
	while (cin >> str && str != "STOP")
	{
		if ( str == "ENQUEUE" )
		{
			cin >> num;
			int ans = isinserted(num);
			if ( ans != -1 ) q[ans].push(num);
			else q[t - 1].push(num);
		}
		else if(str == "DEQUEUE")
        {
        	rep(i, t)
        	{
        		if ( !q[i].empty() )
        		{
        			if (first) first = 0;
        			else cout << " ";
        			cout << q[i].front();
				}
				q[i].pop();
				break;
			}
        }
	}
}

int main()
{
	solve();
	return 0;
}
// AC 的版本
/*
   本来是要用中文写注释的,但是因为今天开始学习使用 codeblocks,codeblocks 上的中文注释又很迷,完全是颠倒过来的,就是说,如果敲出了中文注释,还得偏着头转 90°来看自己的注释...
   
   但是由于以后都是用 codeblocks 来代替之前的日常标配 DevC,所以,凡是写注释,我都想办法写英文吧...要么就不写了 T^T
   
   顺带一提,不愧是 ACM的区域赛标配(虽然我还没有参赛实力,这句话是师兄们说的),补全功能真的太强大了,那些函数什么的,如果一定要找1个小瑕疵,那就是中文注释的方向颠倒,和...括号不能自动补全,这个用惯了 DevC,还真是略有点不适应
   (好像一不小心就找了2个小瑕疵,不过别的地方真的都很不错,值得推荐的 codeblocks!~)
*/
#include <iostream>
#include <queue>
#include <map>
#include <string>
#define rep(i, n) for ( int i = 0; i < n; i++ )
const int maxt = 10;
using namespace std;

void solve ()
{
	int t; // the sum of teams
	int n; // the total number in a team
	int x; // each element
	int first = 1; // check if it is the first element to be output
	string s; // string to store operation command
	map<int, int> team; // which team the element is in
	queue<int> q[maxt]; // real queue
	queue<int> Q4team; // Queue for team

	cin >> t;
	rep(i, t)
	{
		cin >> n;
		rep(j, n)
		{
			cin >> x;
			team[x] = i;
		}
	}

	while ( cin >> s && s != "STOP" )
	{
		if ( s[0] == 'D' ) //dequeue the element first, and the dequeue the team if necessary
		{
			int num = Q4team.front();
			if ( first ) first = 0;
			else cout << " ";
			cout << q[num].front();
			q[num].pop();
			if ( q[num].empty() ) Q4team.pop();
		}

		else if ( s[0] == 'E' ) //If necessary, enqueue the team first, and the enqueue the element
		{
			int num; //num for group
			cin >> num;
			int group = team[num]; // find the team number he is in
			if ( q[group].empty() )  Q4team.push(group);
			q[group].push( num );
		}
	}
}

int main ()
{
	solve ();
	return 0;
}







;