祖玛(Zuma)
2016-04-09 15:49
246 查看
祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干个彩色珠子,其中任意三个相邻的珠子不会完全同色。此后,你可以发射珠子到轨道上并加入原有序列中。一旦有三个或更多同色的珠子变成相邻,它们就会立即消失。这类消除现象可能会连锁式发生,其间你将暂时不能发射珠子。 开发商最近准备为玩家写一个游戏过程的回放工具。他们已经在游戏内完成了过程记录的功能,而回放功能的实现则委托你来完成。 游戏过程的记录中,首先是轨道上初始的珠子序列,然后是玩家接下来所做的一系列操作。你的任务是,在各次操作之后及时计算出新的珠子序列。 输入 第一行是一个由大写字母'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 ; struct group { char wo; int n; }; struct group gro ; struct group myqueue ; 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次数太多了,然而改了之后,却出现了答案错误,最后一个数据仍然是时间超限。。。 图中第三种情况是输入为空,也就是本来就没有小球的情况
相关文章推荐
- no_merge/merge vs no_unnest/unnest
- Android -- SurfaceFlinger 概要分析系列
- Fater-RCNN-Caffe Configuration
- 自然语言中的重要概念——熵(Entropy)
- 单例--使用枚举类型实现
- LeetCode之12---Integer to Roman
- 扫码登录流程
- ubuntu 状态栏没显示时间 解决方法
- 欧拉回路,欧拉路
- 【Android基础】电话拨号器
- linux下 vi 命令
- 极限安全新闻播报(04.09)
- android启动--深入理解init进程
- 【SASS】 一个Opacity混合器(外加如何让背景透明 文字不透明)
- 【剑指offer系列】 从上往下打印二叉树___23
- BottomSheetBehavior底部弹出窗口的用法
- sockjs-web实时通信应用解决方案
- 数据库时间转换
- 第三章:Shiro的配置
- markdown 初体验