1399 - ZOJ问题
对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC。
是否AC的规则如下:
1. zoj能AC;
2. 若字符串形式为xzojx,则也能AC,其中x可以是N个'o' 或者为空;
3. 若azbjc 能AC,则azbojac也能AC,其中a,b,c为N个'o'或者为空;
Input
输入包含多组测试用例,每行有一个只包含'z','o','j'三种字符的字符串,字符串长度小于等于1000。
Output
对于给定的字符串,如果能AC则请输出字符串“Accepted”,否则请输出“Wrong Answer”。
Examples
Input
zoj ozojo ozoojoo oozoojoooo zooj ozojo oooozojo zojoooo
Output
Accepted Accepted Accepted Accepted Accepted Accepted Wrong Answer Wrong Answer
Hint
怎样的字符串才是符合条件的呢?这个需要仔细分析题目描述中的三个条件。前两个条件比较简单,主要分析第三个条件。我们注意前两个条件,每个条件只确定了一个比较明显的形式,第三个条件每次变换就会有很多形式了。那么,通过条件三的变换会得到怎样的形式呢?条件三的变化必然是基于一个初始状态的,这个初始状态就来自于条件一或者条件二。如果条件三种的a不为空,则经过条件三变换后就不能得到符合条件一和条件二的形式了,因为经过条件三变换后的形式中z与j之间的o的数目大于1,而在前两个条件当中中间o的数目只能为1。再仔细观察条件三的初始状态会发现起始时,a和c中o的数目是相同的,这样每次经过条件三的变换z与j之间会增加一个o,而j之后会增加与a中相同数目的o。因而最终j之后o的数目是z之前o数目与z和j之间o数目的乘积。
Solution C
#include <stdio.h> #include <string.h> #define SIZE 1000 int main() { char line[SIZE]; while(1) { if(scanf("%s",line)==EOF) { break; } int len =strlen(line); int inz=strchr(line,'z')-line; int inj=strchr(line,'j')-line; if(inj<0||inz<0) { printf("Wrong Answer\n"); continue; } int count=inj-inz-1; int flag=0; if(count>=1) { for(int i=inj+1;i<len;i++) { if(line[i]!='o') { flag=1; break; } } for(int i=inz+1;i<inj;i++) { if(line[i]!='o') { flag=1; break; } } if(flag==1) { printf("Wrong Answer\n"); continue; } int result=len-inj-1; for(int i=count;i>=1;i--) { result=result-inz; if(result<=0) { break; } } if(result!=0) { printf("Wrong Answer\n"); } else if(result==0) { printf("Accepted\n"); } } else if(count<1) { printf("Wrong Answer\n"); } } }
Solution C++
#include <stdio.h> bool Judge(char *str){ // 判断字符串是否符合要求 int oBeforeZ=0, oMid=0, oAfterJ=0; // 分别存储 z 前面、z 与 j 之间以及 j 之后的o的数目。 int i = 0; while(str[i] && str[i]=='o'){ // 计算 z 之前的 o 的数目,这里注意不能超出字符串边界(用 str[i]来判断,下同) i++; oBeforeZ++; } if(str[i] != 'z'){ // 如果第一次遍历 o 结束后的字符不是 z 则不符合要求 return false; } i++; while(str[i] && str[i]=='o'){ // 计算 z 与 j 之间 o 的数目 i++; oMid++; } if(!oMid || str[i]!='j'){ // 如果中间没有 o 或者中间 o 之后的字符不是 j,则不符合 return false; } i++; while(str[i] && str[i]=='o'){ // 计算 j 之后 o 的数目 i++; oAfterJ++; } if(str[i]){ // 如果 j 之后的 o 都统计完了还没有到达字符串结尾,则不符合 return false; } return oBeforeZ*oMid == oAfterJ; // 只有 z 前面 o 的数目与中间 o 数目的乘积与 j 后面 o 的数目相同,才符合 } int main(){ char str[1100]; // 用来读入字符串 while(scanf("%s", str) != EOF){ puts(Judge(str) ? "Accepted" : "Wrong Answer"); } return 0; }
Hint
怎样的字符串才是符合条件的呢?这个需要仔细分析题目描述中的三个条件。前两个条件比较简单,主要分析第三个条件。我们注意前两个条件,每个条件只确定了一个比较明显的形式,第三个条件每次变换就会有很多形式了。那么,通过条件三的变换会得到怎样的形式呢?条件三的变化必然是基于一个初始状态的,这个初始状态就来自于条件一或者条件二。如果条件三种的a不为空,则经过条件三变换后就不能得到符合条件一和条件二的形式了,因为经过条件三变换后的形式中z与j之间的o的数目大于1,而在前两个条件当中中间o的数目只能为1。再仔细观察条件三的初始状态会发现起始时,a和c中o的数目是相同的,这样每次经过条件三的变换z与j之间会增加一个o,而j之后会增加与a中相同数目的o。因而最终j之后o的数目是z之前o数目与z和j之间o数目的乘积。