运行出来结果对了为什么提交到PAT上去一个测试点过不了

Martin Morning 2019-07-04 08:07:13
1003 我要通过! (20 分)
“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。

得到“答案正确”的条件是:

字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;
任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或者是仅由字母 A 组成的字符串;
如果 aPbTc 是正确的,那么 aPbATca 也是正确的,其中 a、 b、 c 均或者是空字符串,或者是仅由字母 A 组成的字符串。
现在就请你为 PAT 写一个自动裁判程序,判定哪些字符串是可以获得“答案正确”的。

输入格式:

每个测试输入包含 1 个测试用例。第 1 行给出一个正整数 n (<10),是需要检测的字符串个数。接下来每个字符串占一行,字符串长度不超过 100,且不包含空格。

输出格式:

每个字符串的检测结果占一行,如果该字符串可以获得“答案正确”,则输出 YES,否则输出 NO。

输入样例:

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
输出样例:

YES
YES
YES
YES
NO
NO
NO
NO


代码如下
#include<stdio.h>
#include<string.h>

int main(){
int n,i,j;
int cntp=0,cntt=0,cnta=0,flag=1;

char *p1,*p2;
scanf("%d",&n);
char s[100][100];
for(i=0;i<n;++i)
{
scanf("%s",s[i]);
}


for(i=0;i<n;++i)
{

for(j=0;s[i][j]!='\0';j++)
{
if(s[i][j]=='P') cntp++;
else if(s[i][j]=='A') cnta++;
else if(s[i][j]=='T') cntt++;
else {flag=2; break;}
}
if(flag==1&&cntp==1&&cntt==1&&cnta!=0)
{
p1=strchr(s[i],'P');
p2=strchr(s[i],'T');

if((p1-s[i])*(p2-p1-1)==strlen(p2)-1)
flag=0;
}
if(flag==0) puts("YES");
else puts("NO");
}
printf("%d",p1-s[i]);

return 0;
}
...全文
621 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Martin Morning 2019-07-07
  • 打赏
  • 举报
回复
引用 4 楼 coo135 的回复:
智商有限,这道题目实在是看不懂啊……
能弄明白在讲什么的真是神仙啊!!!

百度到有位神仙他明白,解释如下:

解决问题的关键是第二个和第三个要求。

(1)第二个要求说明了a的长度和c的长度是相等的,所以我们可以列出一个等式:lena = lenc;

(2)第三个要求则说明,在第二个条件成立的条件下,将aPATc中的A字符换成b串,变为aPbTc。如果该字符串正确,那么aPbATac字符串也正确。仔细观察不难发现,P和A字符中间多加了一个A字符,而字符串末尾c串后面则加了一个a串。也就是说,c串后面加的a串的个数与P字符和T字符中间加入的A字符的个数相等。

假设b含有lenb个A字符,那么新加入的A字符的个数就是(lenb-1)个(因为为了保证字符串正确,b中最起码要有一个A字符)。所以c串后面的a串个数也就是(lenb-1)个。所以可以列出一个式子: lenc = lenc+(lenb-1)*lena 。

由第二个要求得出的式子 lena = lenc 带入得: lenc = lena + (lenb-1)*lena 。

化简上式即为 : lenc = lena * lenb。


原来如此~~~~拜一下~~~这样写代码就简单了

#include <stdio.h>
#include <string.h>
// 解题关键 (len_a)P(len_b)T(len_c)
// 例:AAPATAA, len_a=2,len_b=1,len_c=2
// 判断条件:len_c = len_a * len_b,并且len_b>=1。

//judge,符合要求,返回1,否则返回0
int judge(char str[]) {
int len_a, len_b, len_c;// 'A' 的个数
char* p, * t;
//字符串中有非'P'、'A'、'T'字符,不符合要求
for (char* s = str; *s != '\0'; s++) {
if (*s != 'P' && *s != 'A' && *s != 'T')
return 0;
}
// 找出'P','T' 在字符串中的位置
p = strchr(str, 'P');
t = strchr(str, 'T');
//未找到字符'P','T' 或者'T'在'P'之前,说明不符合要求
if (p == NULL || t == NULL || p > t) return 0;
//求a,b,c 长度
len_a = p - str;
len_b = t - p - 1;
len_c = strlen(t + 1);
//根据条件,进行判断
if (len_b >= 1 && len_c == len_a * len_b)
return 1;
else
return 0;
}
int main()
{
int n;
char str[10][101];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%s", str[i]);
if (judge(str[i]) == 1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}

我知道是啥意思,我的代码思路和你的一样,而且我运行出来的结果都是对的。只是提交进PAT测试点全错了。我刚又在牛客网上去提交了一遍发现全过了,这不是我第一次碰到这种情况了。我觉得PAT的判题系统可能有BUG
coo135 2019-07-07
  • 打赏
  • 举报
回复
智商有限,这道题目实在是看不懂啊……
能弄明白在讲什么的真是神仙啊!!!

百度到有位神仙他明白,解释如下:

解决问题的关键是第二个和第三个要求。

(1)第二个要求说明了a的长度和c的长度是相等的,所以我们可以列出一个等式:lena = lenc;

(2)第三个要求则说明,在第二个条件成立的条件下,将aPATc中的A字符换成b串,变为aPbTc。如果该字符串正确,那么aPbATac字符串也正确。仔细观察不难发现,P和A字符中间多加了一个A字符,而字符串末尾c串后面则加了一个a串。也就是说,c串后面加的a串的个数与P字符和T字符中间加入的A字符的个数相等。

假设b含有lenb个A字符,那么新加入的A字符的个数就是(lenb-1)个(因为为了保证字符串正确,b中最起码要有一个A字符)。所以c串后面的a串个数也就是(lenb-1)个。所以可以列出一个式子: lenc = lenc+(lenb-1)*lena 。

由第二个要求得出的式子 lena = lenc 带入得: lenc = lena + (lenb-1)*lena 。

化简上式即为 : lenc = lena * lenb。


原来如此~~~~拜一下~~~这样写代码就简单了

#include <stdio.h>
#include <string.h>
// 解题关键 (len_a)P(len_b)T(len_c)
// 例:AAPATAA, len_a=2,len_b=1,len_c=2
// 判断条件:len_c = len_a * len_b,并且len_b>=1。

//judge,符合要求,返回1,否则返回0
int judge(char str[]) {
int len_a, len_b, len_c;// 'A' 的个数
char* p, * t;
//字符串中有非'P'、'A'、'T'字符,不符合要求
for (char* s = str; *s != '\0'; s++) {
if (*s != 'P' && *s != 'A' && *s != 'T')
return 0;
}
// 找出'P','T' 在字符串中的位置
p = strchr(str, 'P');
t = strchr(str, 'T');
//未找到字符'P','T' 或者'T'在'P'之前,说明不符合要求
if (p == NULL || t == NULL || p > t) return 0;
//求a,b,c 长度
len_a = p - str;
len_b = t - p - 1;
len_c = strlen(t + 1);
//根据条件,进行判断
if (len_b >= 1 && len_c == len_a * len_b)
return 1;
else
return 0;
}
int main()
{
int n;
char str[10][101];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%s", str[i]);
if (judge(str[i]) == 1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}


Martin Morning 2019-07-07
  • 打赏
  • 举报
回复
引用 12 楼 coo135的回复:
1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;

题目中的条件1规定了。

你做PAT,建议做甲级或以上的,乙级基本不需要算法,对学习帮助不大。
比较推荐做:数据结构与算法题目集,这些程序相对较为复杂,对编程帮助比较大。

好的,谢谢你的建议,我明天改刷算法题集,甲级英文题目理解起来有点浪费时间,暂时先不做了
coo135 2019-07-07
  • 打赏
  • 举报
回复
1.字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符;

题目中的条件1规定了。

你做PAT,建议做甲级或以上的,乙级基本不需要算法,对学习帮助不大。
比较推荐做:数据结构与算法题目集,这些程序相对较为复杂,对编程帮助比较大。

Martin Morning 2019-07-07
  • 打赏
  • 举报
回复
引用 10 楼 coo135 的回复:
相信这次说到点子上了……

错误如下图所标,有2处。
1:flag在循环中没有被重置,这个错误是比较明显的,所以我就认为逻辑有问题,没有细看你的程序。抱歉。
if (flag == 1 && cntp == 1 && cntt == 1 && cnta != 0)
当flag置为2时,不管对错,都将一直输出NO;
测试用例1:输出8个NO。
8
PT
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
Whatever
APAAATAA

2:计数器没有重置,这是刚刚调试时发现的问题。

解决:在 for (i = 0; i < n; ++i)后增加重置语句:
flag = 1;
cntp = cnta = cntt = 0;


修改后PAT结果:
我怎么就没想到呢。感谢老哥的指导,这道题是我很久以前发的贴了,现在才找到BUG,结果还是这种低级错误。然后我还想问一点就是如果按照题目这种说法,为什么PT输出是NO,题目里隐含了 “字符串里必须有A”和“PT之间必须有A的哪一种条件吗?
coo135 2019-07-07
  • 打赏
  • 举报
回复
相信这次说到点子上了……

错误如下图所标,有2处。
1:flag在循环中没有被重置,这个错误是比较明显的,所以我就认为逻辑有问题,没有细看你的程序。抱歉。
if (flag == 1 && cntp == 1 && cntt == 1 && cnta != 0)
当flag置为2时,不管对错,都将一直输出NO;
测试用例1:输出8个NO。
8
PT
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
Whatever
APAAATAA

2:计数器没有重置,这是刚刚调试时发现的问题。

解决:在 for (i = 0; i < n; ++i)后增加重置语句:
flag = 1;
cntp = cnta = cntt = 0;


修改后PAT结果:



Martin Morning 2019-07-04
  • 打赏
  • 举报
回复
引用 1 楼 636f6c696e的回复:
估计是调试打印影响了,你删掉试试 printf("%d",p1-s[i]);
这个是我后面加上去的,忘删了。加上去之前就错了
Martin Morning 2019-07-04
  • 打赏
  • 举报
回复
这个是我后面加上去的,忘删了。加上去之前就错了
636f6c696e 2019-07-04
  • 打赏
  • 举报
回复
估计是调试打印影响了,你删掉试试 printf("%d",p1-s[i]);

70,012

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧