祖玛(Zuma)

祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干个彩色珠子,其中任意三个相邻的珠子不会完全同色。此后,你可以发射珠子到轨道上并加入原有序列中。一旦有三个或更多同色的珠子变成相邻,它们就会立即消失。这类消除现象可能会连锁式发生,其间你将暂时不能发射珠子。

开发商最近准备为玩家写一个游戏过程的回放工具。他们已经在游戏内完成了过程记录的功能,而回放功能的实现则委托你来完成。

游戏过程的记录中,首先是轨道上初始的珠子序列,然后是玩家接下来所做的一系列操作。你的任务是,在各次操作之后及时计算出新的珠子序列。

输入
第一行是一个由大写字母'A'~'Z'组成的字符串,表示轨道上初始的珠子序列,不同的字母表示不同的颜色。

第二行是一个数字n,表示整个回放过程共有n次操作。

接下来的n行依次对应于各次操作。每次操作由一个数字k和一个大写字母Σ描述,以空格分隔。其中,Σ为新珠子的颜色。若插入前共有m颗珠子,则k ∈ [0, m]表示新珠子嵌入之后(尚未发生消除之前)在轨道上的位序。

输出
输出共n行,依次给出各次操作(及可能随即发生的消除现象)之后轨道上的珠子序列。

如果轨道上已没有珠子,则以“-”表示。

Example
Input

ACCBA
5
1 B
0 A
2 B
4 C
0 A
Output

ABCCBA
AABCCBA
AABBCCBA
-
A
限制
0 ≤ n ≤ 10^4

0 ≤ 初始珠子数量 ≤ 10^4

时间:2 sec

内存:256 MB


总的思路是先开个大的字符数组,把数据先存进去,然后开个大的结构体数组,两个数据成员,一个是表示颜色的,一个是表示这个颜色的球的个数,
比如0  A     1   A      2   B,
那么gro[0].wo = A,gro[0].n = 2;gro[1].wo = B, gro[1].n = 1.  
遍历一遍存放数据的数组,把颜色和个数存入结构体数组中,全部遍历完之后。输入要插入的位置和颜色。插入进去后,先判断插入后有没有大于等于3且颜色相同的,有的话,则将等于3的结构体中的两个值均赋值为0,从插入的位置向两边进行遍历直到两边相加没有大于等于3或者颜色不同或者两者既不大于等于3也颜色不同的为止,再进行收缩处理。
,
#include "stdio.h"
#define N 2000000

char zuma[N];
struct group
{
	char wo;
	int n;
};

struct group gro[N];
struct group myqueue[N];

int clear_zuma(int pos, int num)
{
	int j, k, flag = 1, count = 0;
	if (gro[pos].n == 3)
	{
		gro[pos].n = 0;
		gro[pos].wo = '0';
		for (j = pos - 1, k = pos + 1; j >= 1 && k <= num; j--, k++)
		{
			if (gro[j].wo == gro[k].wo && gro[j].n + gro[k].n >= 3 && flag)
			{
				gro[j].n = 0;
				gro[j].wo = '0';
				gro[k].n = 0;
				gro[k].wo = '0';
			}
			else if (gro[j].wo == gro[k].wo && gro[j].n + gro[k].n == 2 && !count)
			{
				gro[j].n++;
				gro[k].n = 0;
				gro[k].wo = '0';
				flag = 0;
				count = 1;
				break;
			}
			else
			{
				count = 1;
				flag = 0;
				break;
			}
		}
	}
	return 0;
}

int shrink(int *num)
{
	int flag = 0, j = 1, i, k;
	int cnt = *num;
	for (i = 1; i <= *num; i++)
	{
		if (gro[i].n)
		{
			myqueue[j++] = gro[i];
			gro[i].n = 0;
			gro[i].wo = '0';
			flag = 1;
		}
		else
		{
			cnt--;
		}
	}
	if (flag == 1)
	{
		for (k = 1; k <= j - 1; k++)
		{
			gro[k] = myqueue[k];
		}
		*num = j - 1;
	}
	else
	{
		*num = cnt;
	}
	return 0;
}

int main()
{
	char ch;
	int num = 1, test, gro_flag = 1;
	while ((ch = getchar()) >= 'A' && ch <= 'Z')
	{
		zuma[num++] = ch;
	}
	if (zuma[1] == 0)
	{
		gro_flag = 0;
	}
	else
	{
		gro[1].wo = zuma[1];
		gro[1].n++;
		int m;
		for (m = 2; m <= num - 1; m++)
		{
			if (zuma[m] == gro[gro_flag].wo)
			{
				gro[gro_flag].n++;
			}
			else
			{
				gro_flag++;
				gro[gro_flag].wo = zuma[m];
				gro[gro_flag].n++;
			}
		}
	}

	scanf("%d", &test);

	while (test--)
	{
		int position, count = 0;
		char word;
		scanf("%d %c", &position, &word);
		if (!gro_flag)
		{
			gro[1].n = 1;
			gro[1].wo = word;
			gro_flag++;
		}
		else
		{
			int i;
			for (i = 1; i <= gro_flag; i++)
			{
				count += gro[i].n;//找到要插入的位置,因为结构体的n成员不是1就是2,所以可以分几种情况来插入
				if (position < count)
				{
					if (gro[i].wo == word)要插入的位置的原小球颜色和要插入的颜色相同
					{
						gro[i].n++;
						if (gro[i].n == 3)//插入进去后如果同颜色的小球个数等于3
						{
							clear_zuma(i, gro_flag);//进行清理,将大于等于3个数的小球清理,赋值为空
							shrink(&gro_flag);进行收缩,把结构体数组没有被赋值为0的元素全部往前移,因为清理之后,数组中必然有些地方是被清理的,也就是被赋值为空的地方
						}
						break;
					}
					else
					{
						if (position == 0)//要插入的位置是第一个位置
						{
							gro_flag++;
							int k;
							for (k = gro_flag; k > 1; k--)
							{
								gro[k] = gro[k - 1];
							}
							gro[1].n = 1;
							gro[1].wo = word;
							clear_zuma(i, gro_flag);//进行清理
							shrink(&gro_flag);//收缩,将未消除的小球全部移动到前面
							break;
						}
						else
						{	//要插入的小球颜色与想插入的位置上的小球前后颜色均不同
							gro_flag += 2;
							gro[i].n--;
							int j, temp = 1;
							for (j = gro_flag; j >= i + 3; j--)
							{
								gro[j] = gro[j - 2];
							}
							gro[j - 1].n = 1;
							gro[j - 1].wo = word;
							gro[j].n = 1;
							gro[j].wo = gro[j - 2].wo;
							break;
						}

					}
				}
				else if (position == count)
				{
					if (gro[i].wo == word)
					{
						gro[i].n++;
						if (gro[i].n == 3)
						{
							clear_zuma(i, gro_flag);
							shrink(&gro_flag);
						}
						break;
					}
					else if (gro[i + 1].wo == word)
					{
						gro[i + 1].n++;
						if (gro[i + 1].n == 3)
						{
							clear_zuma(i + 1, gro_flag);//进行清理
							shrink(&gro_flag);//收缩
						}
						break;
					}
					else
					{
						gro_flag++;
						int j;
						for (j = gro_flag; j > i + 1; j--)
						{
							gro[j] = gro[j - 1];
						}
						gro[j].n = 1;
						gro[j].wo = word;
						break;
					}
				}

			}
		}
		if (!gro_flag)
		{
			printf("-\n");
		}
		else
		{
			int q;
			for (q = 1; q <= gro_flag; q++)
			{
				if (gro[q].n == 2)
				{
					printf("%c%c", gro[q].wo, gro[q].wo);
				}
				else
				{
					printf("%c", gro[q].wo);
				}
			}
			printf("\n");
		}
	}
	return 0;
}//不知道图片能不能显示出来,这个代码只能过掉95%的数据,最后一个百度了下,说是调用printf次数太多了,然而改了之后,却出现了答案错误,最后一个数据仍然是时间超限。。。  图中第三种情况是输入为空,也就是本来就没有小球的情况
祖玛(Zuma)_第1张图片

你可能感兴趣的:(Tsinghua)