题意:
如果射出的球击中球链,且此时生成的新链中相同颜色的球大于等于3个。则这些球可以被消除。
例如,你有一串链是:112233。此时你射出一个2的球,球击中了链中的第一个2(第3个球),此时链变成:1122233
因为中间的2有3个,满足消除的条件,他们会被消除,于是你获得:
1133
消除可以连击,例如:11221133,射出2还是击中第一个2。此时链变成112221133,消除2后,链变成:
111333
前后两串1拼接在一起后,形成四个1,又满足消除条件,继续消除,得到:
33
注意连击只能发生在重新拼接的场合,如果原来的链就可以消除,不是通过拼接达到消除条件,则不能消除。
举例来说:
当前链是11122333,射出2击中第一个2,此时中间形成3个2:111222333,2个2被消除,得到111333。
尽管此时前后的1和3都满足消除条件,但他们不是拼接之后达到消除条件的,因此不能产生连击,最后的结果就是:
111333
基于上述的要求,我们将球组织成带头节点的双向循环链表的形式。请你编写消除的函数完成消除工作。
思路:
①创建两个指针分别指向与插入点相同数字的最前与最后处。若与插入球相同的球≥3则消除相同的球,否则直接退出。
②第一步删除相同球后,如果p,n指针重合,说明已经无球,退出;或者p的数字不等于n的数字,说明无法消除,也退出。若没进上述情况,则将node更新为p或n(若p没指向头节点则更新为p否则更新为n)。
源码:
//struct DUAL_NODE {
// DUAL_NODE* prev;
// DUAL_NODE* next;
// int color;
//};
void hit_zuma_chain(DUAL_NODE* head, DUAL_NODE* node) {
while (1) {
int num = 0;
DUAL_NODE* p = node->prev;
DUAL_NODE* n = node->next;
while (node->color == p->color && p != head) { //指向与插入点相同的最前面一个球
p = p->prev;
num++;
}
while (node->color == n->color && n != head) { //指向与插入点相同的最后面一个球
n = n->next;
num++;
}
if (num > 1) { //若能消除
while (p->next != n) { //消除相同球
DUAL_NODE* t = p->next;
p->next = t->next;
t->next->prev = p;
delete t;
}
p->next = n; //更新p与n指针
n->prev = p;
if (n == p || n->color != p->color) //判断循环能否继续
break;
if (p != head) //更新插入点指针
node = p;
else
node = n;
}
else
break;
}
}
ps:无
双向循环链表实现球链消除算法
这篇博客介绍了一种基于双向循环链表的数据结构,用于实现球链消除游戏的逻辑。当新射出的球与链中某球相同时,会检查是否能形成长度大于等于3的相同颜色球序列进行消除。如果可以,就删除这些球并可能触发连击。文章提供了详细的消除函数实现,包括如何找到相同颜色球的边界,以及如何更新链表结构。在消除过程中,只有当通过拼接球才能满足消除条件时,才会发生连击。
2716

被折叠的 条评论
为什么被折叠?



