这一题是TsingHua OJ上的一道题目,学堂在线的一位数据结构老师的题目(原创),所以我直接把题目先贴下来了,这道题对复习双向链表很有帮助,而且也对数据结构中List,也就是对列表的回顾也是很有帮助的。


祖玛(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


解题思路:

  这道题考察的就是大家对列表的理解和DIY重构能力,模拟Zuma这一远近闻名的游戏中的色块序列。

  我们来回顾一下数据结构的两个基本结构 向量(vetor)和列表(List),这两个数据结构非常类似,但是两种结构的优势和构造却也有很大差距,Vetor实质就是一个可以动态增长空间的数组,也就是通俗的动态数组,可以方便得对数据进行动态管理。

  但是Vetor相对于List却让人觉得有些静态了,因为List的实质是一个双向链表,因此可以比Vetor更加高效得insert或者delete数据,但是List不能随意查询到其中的数据,需要通过指针一次次得遍历查找,即便可以从首部或者尾部查找,但总得来说,每一次遍历的时间度依然是O(n)。

  Ps:另外有一个特别注意的地方,当数据量比较大的时候,每次输出都会调用一次I/O接口(即printf OR cout),这样会造成大量调用,如果按照最坏情况,最大数组有20000个字符,最大输出有10000次,因此调用量可能会达到10^8次,如此大的调用量显然会在数据极端的时候爆出TLE,因此我们也应该对I/O调用的次数也要优化,我这里直接用一个非常大的数组存储所有情况,直到最后输出。

  如果没有这个优化,在TsingHhua OJ上只能通过95%的数据,最后一个测试用例是过不了的。

  Ps:然后注意数据中输入序列可以为空。(length==0的情况刚开始一直没注意,所以第二个测试用例一直过不了。。。ヾ(。`Д´。),做这道题就因为这个耗时一小时啊!!)

    所以注意输入数据的时候用gets()之类读取行字符的函数。

 Ok,贴Code!

  

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; #define MAX 200000000 /*祖玛色块类*/
struct Zuma{
char date;
Zuma *up;
Zuma *down;
Zuma(){};
Zuma(char s):date(s){};
}*header,*tailer; //首尾哨兵 char s[MAX];
int length; //链表长度
int k; //记录数据长度 /*双向链表-尾插法*/
void Creat_zuma(char *s)
{
header = new Zuma();
header->up = NULL; Zuma *rear = header; //定义尾部指针-穿针
for (int i = ; i < length; i++)
{
Zuma *p = new Zuma(s[i]);
rear->down = p;
p->up = rear; rear = p; //换针
}
tailer = new Zuma();
rear->down = tailer;
tailer->up = rear;
tailer->down = NULL;
} /*遍历查找pos位置的指针*/
Zuma* Find(int pos)
{
int counter = ;
Zuma *p = header;
if (length - pos >= pos) //首部遍历
{
while (counter < pos && p->down != tailer)
{
p = p->down;
counter++;
}
}
else{ //尾部遍历
p = tailer;
counter = length;
while (counter >= pos && p->up != header)
{
p = p->up;
counter--;
}
}
return p;
} /*消除*/
Zuma* Remove(Zuma *cur,char c)
{
while ()
{
Zuma *pre = cur->down;
int counter = ;
while (cur != header && cur->date == c) //向前查重
{
cur = cur->up;
counter++;
}
while (pre != tailer && pre->date == c) //向后查重
{
pre = pre->down;
counter++;
}
if (counter >= ) //重复元素大于三个
{
length -= counter;
Zuma *p1 = cur->down, *p2;
while (p1 != pre) //delete
{
p2 = p1->down;
delete p1;
p1 = p2;
}
cur->down = pre;
if (pre != NULL)
pre->up = cur;
c = cur->date;
}
else break;
}
return cur;
} /*插入*/
void Insert(Zuma *p, char c)
{
Zuma *x = new Zuma(c);
if (p->down != NULL)
{
x->up = p;
x->down = p->down;
p->down->up = x;
p->down = x;
}
else{
x->up = p;
x->down = NULL;
p->down = x;
}
length++;
}
int main()
{
int n;
gets(s);
scanf("%d", &n);
length = strlen(s);
/*搭建*/
Creat_zuma(s); for (int t = ; t < n; t++)
{
char c[];
int pos;
scanf("%d%s", &pos, &c); Zuma *p = Find(pos);
Insert(p, c[]);
Zuma *flag = Remove(p, c[]);
/*Record*/
if (flag == header && flag->down == tailer)
{
s[k++] = '-';
s[k++] = '\n';
}
else{
flag = header;
while (flag->down != tailer)
{
s[k++] = flag->down->date;
flag = flag->down;
}
s[k++] = '\n';
}
/*Single Input*/
if (t == n - )
{
s[k] = '\0';
printf("%s", s);
k = ;
}
}
return ;
}

ACM/ICPC 之 双向链表_构造列表-模拟祖玛 (TSH OJ-Zuma(祖玛))的更多相关文章

  1. ACM/ICPC 之 分治法入门(画图模拟:POJ 2083)

    题意:大致就是要求画出这个有规律的Fractal图形了= = 例如 1 对应 X 2 对应 X  X   X    X  X 这个题是个理解分治法很典型的例子(详情请参见Code) 分治法:不断缩小规 ...

  2. 2013 ACM/ICPC Asia Regional Changsha Online–C (模拟)

    题目描述 略... 题解 注意控制精度即可....变量全部定义成double,结果round就行....妈蛋....被这题目恶心死了.... 代码: #include <iostream> ...

  3. ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))

    一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法.这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将I ...

  4. ACM/ICPC 之 快排+归并排序-记录顺序对(TSH OJ-LightHouse(灯塔))

    TsingHua OJ 上不能使用<algorithm>头文件,因此需要手写快排(刚开始写的时候自己就出了很多问题....),另外本题需要在给横坐标排序后,需要记录纵坐标的顺序对的数量,因 ...

  5. HDU 5874 Friends and Enemies 【构造】 (2016 ACM/ICPC Asia Regional Dalian Online)

    Friends and Enemies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  6. HDU 5873 Football Games 【模拟】 (2016 ACM/ICPC Asia Regional Dalian Online)

    Football Games Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  7. HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)

    HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...

  8. ACM/ICPC竞赛

    ACM知识点分类   第一类:基础算法 (1) 基础算法:枚举,贪心,递归,分治,递推,构造,模拟 (2) 动态规划:背包问题,树形dp,状态压缩dp,单调性优化,插头dp (3) 搜索:dfs,bf ...

  9. Java in ACM/ICPC

    目录 Java在ACM/ICPC中的特点 在ACM/ICPC中使用Java需要注意的问题 Java与高精度计算 1.Java在ACM/ICPC中的特点 Java的语法和C++几乎相同 Java在执行计 ...

随机推荐

  1. thinkphp学习笔记13-15集

    13集: ThinkPHP3.1.3使用视频教程--后台登录验证与自动运行方法_标清.flv 14集: ThinkPHP3.1.3使用视频教程--自定义SESSION处理DB驱动与添加Redis处理驱 ...

  2. vim如何进行分屏操作

    文章转自:http://www.netingcn.com/vim-%E5%88%86%E5%B1%8F%E6%93%8D%E4%BD%9C.html 启动vim打开多个文件并分屏显示: vim -on ...

  3. Linux下的百度云客户端

    项目的github地址:https://github.com/LiuLang/bcloud 安装包以及说明:https://github.com/LiuLang/bcloud-packages 我在百 ...

  4. Web前端开发规范文档(google规范)

    (Xee:其实没什么规范约束,但是养成一种好习惯,何乐而不为?) 区分大小写 xhtml  区分大小写,xhtml要求 标签名 属性名 值都要小写,并且要有双引号和 标签闭合. css 元素名称以及i ...

  5. [译]Mongoose指南 - 验证

    开始前记住下面几点 Validation定义在SchemaType中 Validation是一个内部的中间件 当document要save前会发生验证 验证不会发生在空值上 除非对应的字段加上了 re ...

  6. Runas命令:能让域用户/普通User用户以管理员身份运行指定程序。

    注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在某些情况下,为了安全起见,大部分公司都会使用域控制器或只会给员工电脑user的用户权限,这样做能大大提高安全性和可控性,但由此也带 ...

  7. 网站SEO优化之添加Sitemap文件。

    Sitemap.xml 故名思意就是站点地图文件,可以指引Google spider 收录相应网页.正确地使用Google Sitemap,可以确保让Google spider 不遗漏网站内的任何页面 ...

  8. HDOJ 2444 The Accomodation of Students

    染色判读二分图+Hungary匹配 The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limi ...

  9. 如何查看华为EMUI系统APK源码?

    最近想看一下华为EMUI里面的某些系统APK是如何实现的. 那如何获取系统APK呢? 有两种方式: 1.安装豌豆荚,豌豆荚里有一个应用管理的功能,可以查看手机里的所有应用,包括系统应用. 可以使用该功 ...

  10. 在Mac mini上编译Android源码

    参考文章 1.Android 6.0 源代码编译实践 2.编译Android源码致命错误解决方案 实践过程 1.Mac下安装Ubuntu双系统 (1)Ubuntu版本:Ubuntu 15.10 注:实 ...