介绍一下非常骚气的正则表达式解法,虽然运行起来龟速
#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; } }
每个地方都把’A’‘B’‘C’插入看看就好了,需要注意插入后有多处可消除的地方要同时消除。
菜鸡分享解法 先删去所有能消掉的,剩下的一串相邻的都不是重复的,然后从第一个字符开始,算左右有多少是对称,如abcbab,第三个c的左右有ab关于c左右对称,这个ab就是可以被消去的,则加上c可以消去abccba
一直wrong answer 为什么啊 测试数据都对的啊 哭哭 把数组加大就过了,还加上个cstring头文件
菜鸡分享解法 这个解法不对,hhhh[em:04]
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);
} }
这道题还是得一个个插入再消除,对于先消到不能消了再插,是会出错的,这里举一个例子: 字符串BAABCCBCB 先消再插,答案是8(先消了AACC,再消除3B最后插入,还剩一个)。 然而这题先插再消,插C在最后一个C的旁边是可以消完的
一直wrong answer 为什么啊 测试数据都对的啊 哭哭
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 */
菜鸡分享解法 然后得到了一个巧妙的wa,hhhh
介绍一下非常骚气的正则表达式解法,虽然运行起来龟速
这个题数据不大,所以字符串每个地方每种字母都试试
每个地方都把’A’‘B’‘C’插入看看就好了,需要注意插入后有多处可消除的地方要同时消除。
菜鸡分享解法
先删去所有能消掉的,剩下的一串相邻的都不是重复的,然后从第一个字符开始,算左右有多少是对称,如abcbab,第三个c的左右有ab关于c左右对称,这个ab就是可以被消去的,则加上c可以消去abccba
一直wrong answer 为什么啊 测试数据都对的啊 哭哭
把数组加大就过了,还加上个cstring头文件
菜鸡分享解法
这个解法不对,hhhh[em:04]
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
}
}
}
这道题还是得一个个插入再消除,对于先消到不能消了再插,是会出错的,这里举一个例子:
字符串BAABCCBCB
先消再插,答案是8(先消了AACC,再消除3B最后插入,还剩一个)。
然而这题先插再消,插C在最后一个C的旁边是可以消完的
一直wrong answer 为什么啊 测试数据都对的啊 哭哭
include
include
include
using namespace std;
int del(char *t)
{
char s1[100];
char s2[100];
strcpy(s1,t);
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));
}
}
int main()
{
int i,t;
cin>>t;
for(i=0;i<t;i++)
{
cout<<”case #”<<i<<”:”<<endl;
solve();
}
return 0;
}
不要先消除再添字符,不要先消除再添字符,不要先消除再添字符
菜鸡分享解法
然后得到了一个巧妙的wa,hhhh