?给你一个只含有小写字母的字符串s,请你从左至右在 s 中选择第一个 k 个相邻且相等的字母,并删除它们,使被删去的字符串的左侧和右侧连在一起。你需要对 s 重复进行无限次这样的删除操作,直到无法继续为止。在执行完所有删除操作后,输出最终得到的字符串。
输入 整数k和字符串s,(2<=k<=5,1<=|s|<=1000000)?? ?
输出 输出执行完所有删除操作后最终得到的字符串。
样例输入 3 deeedbbcccbdaa
样例输出 aa
以下代码网络查找并由作者注释翻译,并无任何商业用途,仅供学习交流。
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll; //数字变化从deeedbbcccbdaa
//到 ddbbbdaa
//到 dddaa
//到 aa
const ll maxn = 1e6+10;
ll k;
ll n;
char str[maxn],str1[maxn];
int find1(ll x)
{
ll s=1; //deeedbbcccbdaa 这段find1代码
//第一次进入find1 //第一次相当于从a[0]分别和它后面两个判断是否相同 若相同一次则s+1 最多+2次,变成3
//cout<<x+k<<endl; i<(x+k)(遍历3次的代码) //第二次从a[1]分别和它后面两个判断是否相同 相同则+1
for(int i=x+1;i<(x+k);i++){ //第三次从 a[2]分别和它后面两个判断是否相同 相同则+1
// (i-x)<k(和后面两个判断是否相同的代码)
if(i>n)break;
if(str[i]==str[x]&&(i-x)<k){
//cout<<i<<" "; 下一次进入find1 代码 第一次从a[1] 分别和它后面两个判断是否相同 若相同一次则s+1 最多+2次
s++; //第二次从a[1]分别和它后面两个判断
} //第三次从 a[2]分别和它后面两个判断是否相同 相同则+1
}
//cout<<s<<endl; 根据
if(s==k){
return 1;
}else{
return 0;
}
}
int main(){
cin>>k;
cin>>(str+1);//因为数组第一位为str[0],从str[1]开始输入值,方便使用
n=strlen(str+1);
ll cnt=0;
while(1){//while结束循环的条件是!flag ==1时,即flag==0 找不到连续3个相同的字母时
ll flag=0;
for(int i=1;i<=n;i++){
if(find1(i))//若find1返回的是1,则存在需要连续删除的3个字母
//若find1返回的是0 则不存在需要删除的3个字母
{
i=i+k-1;//改变i的值,使i在连续3个字母的后一位
flag=1;
}else{ //如果返回是0,则直接将当前的字母放入新数组str1中
// 数组str1存放的是删除连续字母后的字母串
str1[++cnt]=str[i];
}
}
if(!flag){//如果找不到终止条件(存在连续的3个相同字母)
break;//结束当前while循环
}
for(int i=1;i<=cnt;i++){//将str1数组完全复制到原来str数组中,更新字母,将删除后的字母串更新到原数组中
str[i]=str1[i]; //依照题目输入样例,具体变化过程如下数字变化从deeedbbcccbdaa
//到 ddbbbdaa
//到 dddaa
//到 aa
}
n=cnt;
cnt=0;//初始化
}
for(int i=1;i<=cnt;i++){
cout<<str1[i];//输出最终结果
}
return 0;
}
/*
2
deeedbbcccbdaa
*/
|