B. DS双向链表—祖玛

B. DS双向链表—祖玛
时间限制
1s
内存限制
128MB
题目描述

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

输入

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

第二行是一个数字n,表示玩家共有n次操作。

接下来的n行依次对应于各次操作。每次操作由一个数字k和一个大写字母描述,以空格分隔。其中,大写字母为新珠子的颜色。若插入前共有m颗珠子,位置0至m-1,则k ∈ [0, m]表示新珠子嵌入在轨道上的位置。


输出

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

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



输入样例1 
ACCBA
5
1 B
0 A
2 B
4 C
0 A

输出样例1
ABCCBA
AABCCBA
AABBCCBA
-
A

该题考察数据结构双向链表的使用,双向链表与普通单链表的区别只在于各个结点还包含一个指针用来指向前一个结点,思路上也比较容易想到,我们发射祖玛后(即插入结点到链表中),需要检查新链表能否被消除,如果可以消除则消除,消除后还需再检查能否继续消除,不能消除则继续“发射祖玛”

下面是代码,具体步骤已经写在注释里了 

#include<iostream>
#include<cstring>
using namespace std;

class Node {//定义结点
public:
	char key;
	Node* next;
	Node* pre;

	Node() {
		key = -1;
		next = NULL;
		pre = NULL;
	}
};

class Blinklist {
public:
	Node* head;
	int len;

	Blinklist() {
		head = new Node();//初始化
		head->next = NULL;
		head->pre = NULL;
		len = 0;
	}
	void create(char* str) {//创造n个结点的链表
		int key;
		Node* p = head;

		for(int i=0;i<strlen(str);i++)
		{
			Node* node = new Node();//新结点
			node->next = NULL;
			node->pre = NULL;

			node->key = str[i];
			node->next = p->next;//连接
			node->pre = p;
			p->next = node;
			p = p->next;
		}
		len = strlen(str);
	}
	bool check() {//检查目前的珠子是否可以消除
		Node* p = head->next;
		while (p&&p->next) {
			Node* q = p;
			int sum = 1;
			while (q->next&&q->key==q->next->key) {
				sum++;//计算重复的有多少个
				q = q->next;
			}
			if (sum >= 3) {//这里需要free被消除的结点
				p->pre->next = q->next;//消除的核心
				return true;//返回true代表已经消除了珠子
			}
			else {
				p = q->next;
			}
		}
		return false;//未消除任何珠子
	}
	bool insert(int pos, char ch) {
		if (!(pos >= 0 && pos < len)) {
			return false;//检查插入位置是否正确
		}
		pos++;
		//先找到第pos-1个位置
		int j = 0;
		Node* p = head;
		while (p && j < pos-1) {
			p = p->next;
			j++;
		}
		Node* node = new Node();
		node->key = ch;
		node->next = p->next;
		node->pre = p;
		if(p->next)//注意这里需要判断p->next是否为空,排除插入到第一个的情况
		p->next->pre = node;
		p->next = node;
		return true;
	}
	void print() {
		Node* p = head->next;
		//先检查轨道上还有没有珠子(单独考虑)
		if (!p) {
			cout << '-' << endl;
			return;
		}
		while (p)
		{
			cout << p->key;
			p = p->next;
		}
		cout << endl;
	}
};

int main() {
	Blinklist blinklist;
	char ch;
	int t, pos;
	char* str = new char[100];
	cin >> str;
	blinklist.create(str);
	cin >> t;
	while (t--) {
		cin >> pos >> ch;
		blinklist.insert(pos, ch);
		while (1) {
			if (blinklist.check()) {//如果成功消除,需要再进行一次检查看看会不会出现连锁消除
				continue;
			}
			else {
				break;
			}
		}
		blinklist.print();
	}
	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZZZWWWFFF_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值