题目


思路
一、核心流程(每次操作的执行步骤)
对每个操作(交换第x和x-1个球),执行以下逻辑:
- 交换相邻球 :用
Swap函数交换a[x]和a[x-1](注意输入的x是 "第 x 个球",对应数组下标x-1,所以实际交换a[x-1]和a[x]); - 检测连续相同球 :分两种情况判断是否有≥3 个连续相同的球:
- 若交换后的两个球颜色相同:同时向左右扩展,统计包含这两个球的连续相同球数量;
- 若交换后的两个球颜色不同:分别检测交换后左边球、右边球的连续相同数量;
- 消除并合并序列 :若连续数量≥3,将后续的球向左移动覆盖这些球,同时缩短序列长度
la; - 输出结果:若序列为空输出 "Over",否则输出当前序列。
二、关键模块详解
1. 交换函数(Swap)
- 作用:交换两个字符的位置,实现相邻球的交换;
- 实现:通过指针直接修改原数组的元素值。
2. 交换后的检测逻辑(核心判断)
情况 1:交换后的两个球颜色相同
- 步骤:
- 初始化
cntL(向左统计的连续相同数)、cntR(向右统计的连续相同数); - 从交换位置
x向右遍历,统计与a[x]相同的球数(cntR); - 从交换位置
x-2向左遍历,统计与a[x]相同的球数(cntL); - 总连续数
cnt = cntL + cntR,若cnt≥3则消除:将x+cntR之后的球向左移动到x-cntL的位置,同时la减去cnt(缩短序列长度)。
- 初始化
情况 2:交换后的两个球颜色不同
- 步骤:
- 检测右边球(
a[x]):从x向右统计连续相同数cnt1,若cnt1≥3则消除; - 检测左边球(
a[x-1]):从x-2向左统计连续相同数cnt2,若cnt2≥3则消除; - 消除逻辑同情况 1:后续球左移,
la缩短。
- 检测右边球(
3. 结果输出
- 每次操作后,若
la(当前序列长度)为 0,输出 "Over";否则输出当前序列; - 每个样例操作结束后输出一个空行。
代码
cpp
#include<stdio.h>
#include<string.h>
char a[35];
int i,j,n,x,t,cnt,la;
void Swap(char* a,char* b){
int t=*a;
*a=*b;
*b=t;
}
void game(){
scanf("%s",a);
la=strlen(a);
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&x);
Swap(&a[x],&a[x-1]);
//交换的元素相等
if(a[x]==a[x-1]){
int cntR=1,cntL=1;
cnt=0;
for(j=x+1;j<la;j++){
if(a[j]==a[x]) cntR++;
else break;
}
for(j=x-2;j>=0;j--){
if(a[j]==a[x]) cntL++;
else break;
}
cnt=cntL+cntR;
//后面的数向前移动
if(cnt>=3){
t=x-cntL;
for(j=x+cntR;j<la;j++){
a[t]=a[j];
t++;
}
la-=cnt;
}
}
else{
int cnt1=1,cnt2=1;
//右数
for(j=x+1;j<la;j++){
if(a[j]==a[x]) cnt1++;
else break;
}
if(cnt1>=3){
t=x;
for(j=x+cnt1;j<la;j++){
a[t]=a[j];
t++;
}
la-=cnt1;
}
//左数
for(j=x-2;j>=0;j--){
if(a[j]==a[x-1]) cnt2++;
else break;
}
if(cnt2>=3){
t=x-cnt2;
for(j=x;j<la;j++){
a[t]=a[j];
t++;
}
la-=cnt2;
}
}
if(la==0)printf("Over\n");
else{
for(j=0;j<la;j++){
printf("%c",a[j]);
}
printf("\n");
}
}
printf("\n");
}
int main(){
int T;
scanf("%d",&T);
while(T--){
game();
}
}