羊村快递站(模拟)

题目描述

马上就要到一年一度的"双十二"了,但是来自青青草原的懒羊羊却不想再次疯狂购物了,因为在"双十一"的时候懒羊羊被羊村快递站惩罚哭了,羊村快递站站长喜羊羊因为看到大家都不及时来取快递,于是整出了如下的一套全新的取件机制:
1、所有新到达的快递都会进入待取通道,先到达的快递先进入待取通道,且位于待取通道口,每次只能在通道口取走一件快递,随后通道里的传送带开始转动让下一件快递位于通道口。
2、当要取的快递不位于待取通道口时,快递站管理员沸羊羊会将快递依次取出放进惩罚通道,直到取到取件羊的快递,最后被放进惩罚通道的位于惩罚通道口,先被放入的最后才能被取出
3、当要取的快递位于惩罚通道口时,会直接取走自己的快递,随后整个通道就会向前移动让下一件快递位于通道口。
4、当要取的快递不位于惩罚通道口时,沸羊羊会将快递依次取出并放入快递车上,直到取到取件羊的快递,放入快递车的快递将会受到终极惩罚:被送回发货地,沸羊羊会将这些被打回的快递记录下来,当这些快递的取件羊来取件的时候,将会被告知取件失败。
5、每件进入惩罚通道的快递都会被记录下来,所以每个取件羊来到的快递站的时候,沸羊羊都会先告诉它要取的快递在哪个通道里。
6、每件快递的取件码和收件羊的取件码是对应的且是唯一的,取件羊会取走和自己取件码对应的快递。

聪明的喜羊羊觉得这套惩罚机制简直酷毙了,肯定能让大家及时来取快递。于是他想先行测试一下这套流程。给出快递的信息,输出每件快递被取走的次序。

输入

第一行一个整数N代表快递个数。(1 第二行N个长度为四的取件码,代表每个快递的取件码(快件到达次序为输入顺序)。(0000-9999)
第三行一个整数Q代表取件人个数。
第四行Q个整数,代表每个人的取件码。

输出

输出N个数,代表每个快递的取件次序(从1开始增加),如果取件失败则输出-1,如果快件最终未被打回也未被取走则输出0。

样例输入 
5
0001 0010 0100 1000 1111
4
0001 1000 0010 0100
样例输出 
1 3 -1 2 0
 解题思路

本题是一个模拟题,根据要求我们可以先定义3个二维字符串数组分别储存每个快递的取件码,每个人的取件码和用来放入惩罚通道的栈(先进后出),两个数组,一个数组用来标记某个人的快递是否被取出和放进惩罚通道和被退回,还有一个数组用来储存快递的取件次数,具体实现就是,遍历每一个人的快递码,判断快递在取件通道还是惩罚通道,若在取件通道,则从头开始遍历找到了直接退出循环,没找到则将前面的快递放进惩罚通道,直到找到为止,若开始在惩罚通道,则开始在惩罚通道里面逆序寻找,若找到了则退出循环,没找到则将前面的快递放进终极惩罚系统,即用来储存快递的取件次数的数组与之对应的位置标记为-1,下面是具体代码。

#include
#include
int main()
{
	//book数组用来标记某个人的快递是否被取或放进惩罚系统或被退回,s数组代表快递被取的序号
	//book数组为0代表在取件通道里,为1代表被取走了和被退回,为2代表在在惩罚通道里
	int book[1010] = { 0 },s[1010] = { 0 };
	//a数组用来储存每个快递的取件码,b数组用来储存每个人要去快递的取件码,x数组代表惩罚通道
	char a[1010][9], b[1010][9], x[1010][9];
	int pa = 0, n, m;//pa用来表示快递被取的序号//n,m分别表示有n个快递,和m个人来去
	scanf("%d", &n);
	int i, j, q;
	for (i = 1; i <= n; i++)
		scanf("%s", a[i]);
	scanf("%d", &m);
	for (i = 1; i <= m; i++)
		scanf("%s", b[i]);
	i = 1; j = 1; q = 0;//i,j,q分别用来控制每个人的取件码,每个快递的取件码,惩罚通道的开口
	while(i<=m)//保证遍历每一个人
	{
		if (book[i] == 0)//如果这个人要去取的快递在取件通道里
		{
			while (j <= n)//保证遍历每一个快递
			{
				if (strcmp(b[i], a[j]) == 0)//如果通道口就是要取的快递
				{
					s[j] = ++pa;//标记取件顺序
					book[i] = 1;//标记这个人的快递已经被取了
					j++; i++;//这个快递和这个人要取的快递已经被取了,
					break;//下一个人开始取
				}
				else//如果这个人要去取的快递在不在取件通道口
				{
					strcpy(x[++q], a[j]);//将这个快递放进惩罚通道里面
					for (int f = i + 1; f <= m; f++)
					{
						if (strcmp(b[f], a[j]) == 0)//找到将要取这个快递的人,告诉他你的快递在惩罚通道
						{
							book[f] = 2;
							break;
						}
					}
					j++;//这个快递已经放进惩罚通道里面了,进行下一个快递
				}
			}
		}
		else if (book[i] == 2)//如果这个人要去取的快递在惩罚通道里
		{
			while (q > 0)//栈不为空的情况下
			{
				if (strcmp(b[i], x[q]) == 0)//如果惩罚通道口就是要取的快递
				{
					for (int f = 1; f <= n; f++)//找到这个快递所对应的位置
					{
						if (strcmp(x[q], a[f]) == 0)
						{
							s[f] = ++pa;//标记取件顺序
							break;
						}
					}
					book[i] = 1;//代表这个快递已经被取了
					q--;//出栈,代表这个快递被取了
					i++;//下一个人开始取
					break;
				}
				else//如果惩罚通道口不是要取的快递
				{
					for (int f = 1; f <= n; f++)//找到这个快递所对应的位置
					{
						if (strcmp(x[q], a[f]) == 0)
						{
							s[f] = -1;//标记为-1代表已经被退回
							break;
						}
					}
					for (int f = i + 1; f <= m; f++)//找到将要取这个快递的人
					{
						if (strcmp(b[f], x[q]) == 0)
						{
							book[f] = 1;//告诉他你的快递已经被退回
							break;
						}
					}
					q--;//出栈,代表这个快递被退回
				}
			}
		}
		if (book[i] == 1)//如果这个快递被退回或者被取
			i++;//下一个人取
	}
	for (int f = 1; f <= n; f++)//打印顺序
		printf("%d ", s[f]);
	return 0;
}

总结:解决模拟类型的题目一定要清楚每个数组所代表的含义,且一定要注意细节,是否有情况漏掉,像我在写这题的时候最后漏掉这个人的快递可能已经被退回的情况,导致死循环,找了半天才找到。

羊村快递站(模拟)_第1张图片

你可能感兴趣的:(题组,c语言)