3194. 字符串消除

爱丽丝_青贝尔克

介绍一下非常骚气的正则表达式解法,虽然运行起来龟速

#include <bits/stdc++.h>
using namespace std;
int del(string s,int pos,string c)
{
    s = s.insert(pos,c);
    int len = s.size();
    regex reg1("(.)\\1+");
    smatch sm;
    while (regex_search(s,sm,reg1)){
        s = regex_replace(s,reg1,"");
    }
    return len - s.size();
}
int main()
{
    int t;
    string s;
    cin>>t;
    for (int cas=0;cas<t;++cas){
        cin>>s;
        int ans = 0;
        for (int j=0;j<s.size()-1;++j){
            ans  = max(ans,del(s,j,"A"));
            ans  = max(ans,del(s,j,"B"));
            ans  = max(ans,del(s,j,"C"));
        }
        printf("case #%d:\n",cas);
        cout<<ans<<endl;
    }
}
风见幽香

这个题数据不大,所以字符串每个地方每种字母都试试

#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
string x[3] = { "A","B","C" };
int Delete(string&str)
{
    int x=0;//消除字符个数
    bool sign = 0;
    for(int i=0;str.size()>0&&i<str.size()-1;i++)
        if (str[i] == str[i + 1])
        {
            x++; int y = 1;
            for (int j = i; j < str.size() - 1; j++)
            if (str[j] == str[j + 1])
                x++,y++;
            else
                break;
            str.erase(i, y);
            sign = 1;
            i--;//从这个地方继续检查
        }
    if (sign)//如果有消除过继续消除
        return x + Delete(str);
    else//没有消除过代表字符串不能再消除了
        return x;
}
int main()
{
    int t;
    cin >> t;
    for (int c = 0; c < t; c++)
    {
        string s;
        cin >> s; int ans = 0;
        for(int i=0;i<s.size();i++)
            for (int j =0; j < 3; j++)
            {
                string tmp(s); tmp.insert(i,x[j]);
                ans=max(ans,Delete(tmp));
            }
        cout << "case #" << c << ":\n" << ans << endl;
    }
}
wsyyjqyjy

这道题还是得一个个插入再消除,对于先消到不能消了再插,是会出错的,这里举一个例子:
字符串BAABCCBCB
先消再插,答案是8(先消了AACC,再消除3B最后插入,还剩一个)。
然而这题先插再消,插C在最后一个C的旁边是可以消完的

10165101247

一直wrong answer 为什么啊 测试数据都对的啊 哭哭

include

include

include

using namespace std;

int del(char *t)
{
char s1[100];
char s2[100];
strcpy(s1,t);

int l1=strlen(s1),l2=0,l=0;
int i;
if (l1==0) {
    return 0;
}
s1[l1]='$';
s1[l1+1]='\0';
for(i=1;i<l1+1;i++)
{
    if (s1[i]!=s1[i-1]){
        if(l==i-1)
            s2[l2++]=s1[i-1];
        l=i;
            }
}
s2[l2]='\0';
if (l1==l2)
    return 0;
return  l1-l2+del(s2);

}

void solve()
{
char t1[100];
cin>>t1;
char t2[100];
int i,len=strlen(t1);
int ans=0;
for( i=0;i<len;i++)
{
strncpy(t2,t1,i);t2[i]=’\0’;strcat(t2, “A”);strcat(t2, t1+i);
ans=max(ans,del(t2));
strncpy(t2,t1,i);t2[i]=’\0’;strcat(t2, “B”);strcat(t2, t1+i);
ans=max(ans,del(t2));
strncpy(t2,t1,i);t2[i]=’\0’;strcat(t2, “C”);strcat(t2, t1+i);
ans=max(ans,del(t2));
}

cout<<ans<<endl;

}

int main()
{
int i,t;
cin>>t;
for(i=0;i<t;i++)
{
cout<<”case #”<<i<<”:”<<endl;
solve();
}
return 0;
}

爱丽丝_青贝尔克

不要先消除再添字符,不要先消除再添字符,不要先消除再添字符

徐摆渡
#include <bits/stdc++.h>
using namespace std;
//模拟每个位置都试一遍

int T, cnt;
string str;

int rmov(string s)
{
    string temp=s;
    string ans="";
    int len=s.length();
    int i ,j ,flag=1;
    while(s!=ans){
        i=0, j=0, len=s.length();
        while(i<len){
            if(len==1) {ans=s;break;}
            if(s[i]!=s[i+1]) {
                ans+=s[i];
                i++;//虚指针后移
            }
            else {
                for(j=i+1;j<len&&s[j]==s[i];++j);
                i=j;
            }
        }
        if(s!=ans) {
            s=ans;
            ans="";
        }
    }
    return temp.length()-ans.length();
}

string add(string s, int pos, char ch)//在pos位置后插入字符
{
    string ans="";
    int len=s.length();
    for(int i=0;i<len;++i){
        ans+=s[i];
        if(i==pos) ans+=ch;
    }
    return ans;
}
int main()
{
    cin>>T;
    while(T--){
        cin>>str;
        int _max=0;
        int len=str.length();
        string temp=str;
        str='A'+str;_max=max(_max,rmov(str));
        str=temp;
        str='B'+str;_max=max(_max,rmov(str));
        str=temp;
        str='C'+str;_max=max(_max,rmov(str));
        str=temp;
        for(int i=0;i<len;++i){
            str=add(str,i,'A');_max=max(_max,rmov(str));
            str=temp;
            str=add(str,i,'B');_max=max(_max,rmov(str));
            str=temp;
            str=add(str,i,'C');_max=max(_max,rmov(str));
            str=temp;
        }
        printf("case #%d:\n",cnt++);
        cout<<_max<<endl;
    }
    return 0;
}
/*
3
ABCBCCCAA
AAA
ABC

*/
10165101157

菜鸡分享解法
然后得到了一个巧妙的wa,hhhh

10175102213

每个地方都把’A’‘B’‘C’插入看看就好了,需要注意插入后有多处可消除的地方要同时消除。

10165101157

菜鸡分享解法
先删去所有能消掉的,剩下的一串相邻的都不是重复的,然后从第一个字符开始,算左右有多少是对称,如abcbab,第三个c的左右有ab关于c左右对称,这个ab就是可以被消去的,则加上c可以消去abccba

10165101157

一直wrong answer 为什么啊 测试数据都对的啊 哭哭
把数组加大就过了,还加上个cstring头文件

10165101157

菜鸡分享解法
这个解法不对,hhhh[em:04]

10165101131

include

include

include

int MAX(int a,int b){
if(a>=b) return a;
else return b;
}

int del(char *ostr){
char str[101],t[101];
strcpy(str,ostr);
int slen=strlen(str),lent=0,i,l=0;//slen为原始字符串的长度,lent为消除后剩余字符串的长度
if(slen==0) return 0;
str[slen]=’$’;
str[slen+1]=’\0’;
for(i=0;i<slen+1;i++){
if(str[i]!=str[i-1]){ //相邻字符不相等,未被消除的字符保存在数组t中
if(l==i-1) t[lent++]=str[i-1];
l=i;
}
}
t[lent]=’\0’;
if(slen==lent) return 0;
return slen-lent+del(t);
}

int main()
{
char s[101],temp[101];
int m,n;
scanf(“%d”,&m);
for(n=0;n<m;n++){
scanf(“%s”,s);
int i,len=strlen(s),ans=0;
for(i=0;i<=len;i++){
strncpy(temp,s,i);
temp[i]=’\0’;
strcat(temp,”A”);
strcat(temp,s+i);
ans=MAX(ans,del(temp));//insert A
strncpy(temp,s,i);
temp[i]=’\0’;
strcat(temp,”B”);
strcat(temp,s+i);
ans=MAX(ans,del(temp));//insert B
strncpy(temp,s,i);
temp[i]=’\0’;
strcat(temp,”C”);
strcat(temp,s+i);
ans=MAX(ans,del(temp));//insert C
strncmp(temp,s,i);
temp[i]=’\0’;
strcat(temp,”D”);
strcat(temp,s+i);
ans=MAX(ans,del(temp));//insert D
}

printf("case #%d:\n%d\n",n,ans);

}
}

你当前正在回复 博客/题目
存在问题!