-
题目描述:
-
对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC。
是否AC的规则如下:
1. zoj能AC;
2. 若字符串形式为xzojx,则也能AC,其中x可以是N个'o' 或者为空;
3. 若azbjc 能AC,则azbojac也能AC,其中a,b,c为N个'o'或者为空;
-
输入:
-
输入包含多组测试用例,每行有一个只包含'z','o','j'三种字符的字符串,字符串长度小于等于1000。
-
输出:
-
对于给定的字符串,如果能AC则请输出字符串“Accepted”,否则请输出“Wrong Answer”。
-
样例输入:
-
zoj ozojo ozoojoo oozoojoooo zooj ozojo oooozojo zojoooo
-
样例输出:
-
Accepted Accepted Accepted Accepted Accepted Accepted Wrong Answer Wrong Answer
额,这道题快Wrong到吐血,一直不知道哪里考虑的不周全,从0分到20分,到40分,到60分。。。最后终于A了。题目大意:对于满足三条规则的字符串,输出Accepted,否则输出Wrong Answer第一条很好判断,直接判断是否字符串相等;第二条只要判断zoj前后的'o'是否相等,注意这里只能是o,如果出现其他字符,立马排除;第三条规则最难处理,因为它是以递归的形式给出的,规则是若X成立,则Y一定成立。我的思路是要判断Y是否成立,先转换成X的形式,判断X是否成立,成立最好,不成立再递归判断,直到出现不能转换,或者转换后可以立马判断是否符合的情况。答题思路是这样,但实际做的过程中,很多情况刚开始没考虑到。比如z,o,zz,jj,zojzoj,jjzojj都是不符合条件的情况,很容易遗漏。
#include <iostream> using namespace std; int judge1(string str){ if(str == "xx") return 0; if(str == "zoj") return 1; int x = 0; for(int i=0;i<str.length();i++){ if(str[i]=='z'&&str[i+1]=='o'&&str[i+2]=='j'){ x = i; break; } } if(x == 0) return 0; //表示不存在连续的zoj序列 int count1=0,count2=0; for(int i=0;i<x;i++){ if(str[i] != 'o') return 0; else count1++; } for(int i=x+3;i<str.length();i++){ if(str[i] != 'o') return 0; else count2++; } if(count1 == count2) return 1; return 0; } string transition(string str){ int num_a_o = 0; int num_b_o = 0; int num_ac_o = 0; int x1=-1,x2=-1; for(int i=0;i<str.length();i++){ if(str[i] == 'z'){ x1 = i; break; } } if(x1 == -1) return "xx"; //表示序列中没有z出现的一项 for(int i=0;i<str.length();i++){ if(str[i] == 'o'&&str[i+1] == 'j'){ x2 = i; break; } } if(x2 == -1) return "xx"; //表示序列中没有oj连续的一项 for(int i=0;i<x1;i++){ if(str[i] == 'o') num_a_o++; else return "xx"; //表示转换失败 } for(int i=x1+1;i<x2;i++){ if(str[i] == 'o') num_b_o++; else return "xx"; } for(int i=x2+2;i<str.length();i++){ if(str[i] == 'o') num_ac_o++; else return "xx"; } if(num_ac_o<num_a_o) return "xx"; string str1 = ""; for(int i=0;i<num_a_o;i++) str1 += 'o'; str1 += 'z'; for(int i=0;i<num_b_o;i++) str1 += 'o'; str1 += 'j'; for(int i=0;i<num_ac_o-num_a_o;i++) str1 += 'o'; return str1; } int main(){ string str; while(cin>>str){ if(judge1(str)) cout<<"Accepted"<<endl; else{ if(judge1(transition(str))) cout<<"Accepted"<<endl; else{ bool flag = 0; while(transition(str)!="xx"){ str = transition(str); if(judge1(str)){ cout<<"Accepted"<<endl; flag = 1; break; } } if(flag == 0) cout<<"Wrong Answer"<<endl; } } } return 0; }
当然这只是我比较常规的想法,网上看到大神的思路是这样的,只要判断z前面o的个数*z和j之间o的个数是否等于j后面o的个数。我后来验证了一下,用数学归纳法证明发现是对的,感觉好简单。。不过这不是一般人能够想到的。