1003.我要通过(20)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于PAT的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。
得到“答案正确”的条件是:
1. 字符串中必须仅有P, A, T这三种字符,不可以包含其它字符;
2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
3. 如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a, b, c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
输入格式: 每个测试输入包含1个测试用例。第1行给出一个自然数n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过100,且不包含空格。
输出格式:每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出YES,否则输出NO。
输入样例:8 PAT PAAT AAPATAA AAPAATAAAA xPATx PT Whatever APAAATAA输出样例:
YES YES YES YES NO NO NO NO
题目分析:刚拿到题目的时候会很迷茫,无法找到字符串正确的规则。通过分析三个条件是层层递进的关系。第一个条件:字符串上只有'P','A','T'三个字符组成,所以样例"Whatever"是错的。样例中的"XPATX"中出现了非'P''A''T'的字符,不要看到题目中有xPATx就认为是对的。通过第二个条件你可以得出:n*APATn*A(n是自然数)的形式是正确的,结合条件3可以得出:'P''T'字符都只能有且只有一个。通过条件3,b后面多了一个A,C的后面就多出了一个a,可以得出,Anumber(c)=Anumber(a)*Anumber(b),这很难一眼看出,可以通过样例的前4个进行验证。之后就可以获取字符串,循环计算三个字符的个数对字符串的检验。
下面是我找到的3段代码有C和C++;有的我进行了一些修改,感谢代码作者,举报即删
C语言:
#include <stdio.h>
#include <string.h>
int main()
{
char c[100];
int i,j,n;
int count_P,count_A,count_T,pos_P,pos_T;//PAT三个字符的数量和位置
scanf("%d\n",&n);
for(i=0;i<n;i++)
{
gets(c);
count_P = 0;
count_A = 0;
count_T = 0;
pos_P = 0;
pos_T = 0;
for(j=0;j<strlen(c);j++)
{
if(c[j]=='P')
{
count_P++;
pos_P = j;
}
if(c[j]=='A')
count_A++;
if(c[j]=='T')
{
count_T++;
pos_T = j;
}
}
if(count_P+count_A+count_T != strlen(c) || pos_T-pos_P<=1 || count_P>1 || count_T>1 || pos_P*(pos_T-pos_P-1)!=strlen(c)-pos_T-1)//出现非PAT的字符,PT的位置不对,PT的数量大于1,Anumber(c)!=Anumber(a)*Anumber(b)
printf("NO\n");
else
printf("YES\n");
}
}
C++:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n;
scanf("%d",&n);
char (*input)[101] = (char (*)[101])malloc(n*101*sizeof(char));//分配一个char的数组空间
int i;
for(i=0;i<n;++i)//把数据装进数组中
scanf("%s",input[i]);
bool isPdiscover,isTdisCover,flag;//bool是C++特有的,作者说是用C写的但还是要用C++运行,不过可以改成INT
int aLen,bLen,cLen;
for(i=0;i<n;++i)
{
int j;
isPdiscover = false;
isTdisCover = false;
flag = true;
aLen = bLen = cLen = 0;
for(j=0;input[i][j] != 0;++j)
{
if(input[i][j] == 'P')
{
if(isPdiscover)
{
flag = false;
break;
}
else
{
isPdiscover = true;
aLen = j - aLen;// 求出Anumber(a)的值
}
}
else if(input[i][j] == 'T')
{
if(isTdisCover)
{
flag = false;
break;
}
else
{
isTdisCover = true;
bLen = j - aLen -1;
}
}
else if(input[i][j] != 'A')//判断是否出现了其他字符
{
flag = false;
break;
}
}
if(!flag)
printf("NO");
else if(!isPdiscover || !isTdisCover )
printf("NO");
else if(bLen < 1)
printf("NO");
else if(aLen == 0 && bLen >0 && bLen+2 == j)
printf("YES");
else {
cLen = j - 2- aLen - bLen;
if(cLen == aLen * bLen)
printf("YES");
else
printf("NO");
}
if(i != n-1)
printf("\n");
}
free(input);
}
我将C++的代码转换成C:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define M 100 #define N 100 int main() { int n; //printf("请输入一个自然数:\n"); scanf("%d",&n);//(1)scanf() 以 空格 或 回车符 结束读取,空格 或 回车符 会遗留在缓冲区。//(2)不能直接输入带空格的字符串。//注意:scanf()函数如何才能输入带空格的字符串,应使用:【具体代码和输出内容如下:】char arry[N][M];//建立一个100*100的字符矩阵,将所要输入的字符放进矩阵当中 int i; for(i=0;i<n;i++) scanf("%s",&arry[i]); int isPdiscover,isTdiscover,flag;//isPdiscover是指P字符是否重复,isTdiscover是指T字符是否重复;flag是指字符串的正确与错误 int aLen,bLen,cLen; for(i=0;i<n;i++) { int j; isPdiscover = 0; isTdiscover = 0; flag = 1; aLen=bLen=cLen=0; for(j=0;arry[i][j] != 0;j++) { if(arry[i][j] == 'P') { if(isPdiscover) { flag = 0; break; } else { isPdiscover = 1; aLen = j - aLen; } } else if(arry[i][j] == 'T') { if(isTdiscover) { flag = 0; break; } else { isTdiscover = 1; bLen = j - aLen -1; } } else if(arry[i][j] != 'A') { flag = 0; break; } } if(flag == 0) { printf("NO"); } else if(isPdiscover == 0||isTdiscover == 0) { printf("NO"); } else if(bLen < 1) { printf("NO"); } else if(aLen == 0 && bLen > 0 && bLen+2 == j) { printf("YES"); } else { cLen = j - 2 - aLen - bLen; if(cLen == aLen * bLen) { printf("YES"); } else { printf("NO"); } } if(i != n-1) printf("\n"); } return 0; }//scanf("%[^\n]", a); //%[]输入字符集, [^\n] 表示除了'\n'之外的字符都接收,即可以接收空格,这个可以用来输入带空格的字符串
//可以使用getchar();获取被遗留的\n和\0,gets()会直接舍弃\n
scanf("%[^\n]", a); //%[]输入字符集, [^\n] 表示除了'\n'之外的字符都接收,即可以接收空格,这个可以用来输入带空格的字符串