题目描述
祖玛是一款曾经风靡全球的游戏,其玩法是:在一条轨道上初始排列着若干个彩色珠子,其中任意三个相邻的珠子不会完全同色。此后,你可以发射珠子到轨道上并加入原有序列中。一旦有三个或更多同色的珠子变成相邻,它们就会立即消失。这类消除现象可能会连锁式发生,其间你将暂时不能发射珠子。
给定轨道上初始的珠子序列,然后是玩家所做的一系列操作。你的任务是,在各次操作之后及时计算出新的珠子序列。
输入
第一行是一个由大写字母'A'~'Z'组成的字符串,表示轨道上初始的珠子序列,不同的字母表示不同的颜色。
第二行是一个数字n,表示玩家共有n次操作。
接下来的n行依次对应于各次操作。每次操作由一个数字k和一个大写字母描述,以空格分隔。其中,大写字母为新珠子的颜色。若插入前共有m颗珠子,位置0至m-1,则k ∈ [0, m]表示新珠子嵌入在轨道上的位置。
输出
输出共n行,依次给出各次操作(及可能随即发生的消除现象)之后轨道上的珠子序列。
如果轨道上已没有珠子,则以“-”表示。
输入样例:
ACCBA
5
1 B
0 A
2 B
4 C
0 A
输出样例:
ABCCBA
AABCCBA
AABBCCBA
-
A
这题乍一看可能挺吓人的,慢慢捋清思路,还行吧
#include <iostream>
using namespace std;
class Node {
public:
char data;
Node* next;
Node* prio;
Node() { data = NULL; next = NULL; prio = NULL; }
};
class List {
Node* head;
int len;
public:
List() {
string s;
head = new Node;
head->prio = NULL;//规范性,都初始化为空
head->data = NULL;
cin >> s;
len = s.length();//取字符串长度
Node* p = head;//取头结点
for (int i = 0; i < len; i++) {
Node* q = new Node;//new一个新节点
q->data = s[i];//赋值
p->next = q;
q->prio = p;
p = q;//p右移一位
}
p->next = NULL;//最后为空
}
void list_insert() {
int i;
char item;
cin >> i >> item;
Node* p = head;//用于保存插入结点的前一个节点,注意题目意思第0个不是head
for (int j = 0; j < i; j++) {
p = p->next;
}
Node* q = new Node;
Node* temp;
q->next = p->next;
if(p->next) p->next->prio = q;//注意,每次使用两个单箭头复合都要检查
p->next = q; //接上一句:第一个单箭头是否为空
q->prio = p;
q->data = item;
len++;
int snum = 1;//用来记录重复元素个数
Node* left = q->prio;//插入元素的左边一个元素
Node* right = q->next;//插入元素的右边一个元素
while (true) {//跳出条件在内部break
while (left) {
if (left->data == item) {
snum++;//左边计数
left = left->prio;
}
else {
break;//一旦不相等(说明不连续重复)就跳出
}
}
while (right) {
if (right->data == item) {
snum++;//右边计数
right = right->next;
}
else {
break;//与右边相同
}
}
if (snum >= 3) {
left = left->next;//这句之前left指向左边第一个不重复的元素,所以要处理
while (snum--) {
temp = left;
left = left->next;
list_del(temp);//一定要用一个temp保留之前的left
} //而且不能想着把这一句换成list_del(left.prio),因为left有可能为空
if (left) {//再次检查,重新设置item,snum等参数
snum = 1;
item = left->data;
left = left->prio;
right = right->next;
}
}
else {
break;//跳出大循环
}
}
}
void list_del(Node*p) {
Node* temp = p;
p->prio->next = p->next;
if (p->next) p->next->prio = p->prio;//和上面一样,要判断
len--;
free(temp);
}
void list_disply() {
Node* p = head->next;
if (p) {
for (int i = 0; i < len; i++) {
cout << p->data;
p = p->next;
}
}
else {
cout << "-";
}
cout << endl;
}
};
int main()
{
int n;
List list;
list.list_disply();
cin >> n;
while (n--) {
list.list_insert();
list.list_disply();
}
}