Christopher. 发表于 2021-5-1 20:36:37

请各位大神帮忙看下我的代码哪里有问题

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>

int main(void)
{
        int n;
        int i;
        int result = {0};
    char ch;

        scanf("%d", &n);
    getchar();

        for (i = 0; i < n; i++)
        {
                int p = 0, t = 0, a = 0;
                int flag = 1;   //judge if p a t
                int count0 = 0, count1 = 0, count2 = 0;   //the number of A of different position
                int position = 0;       //the position of A,initial 0,front of P

                while ((ch = getchar()) != '\n')
                {
                        if (ch == 'P')
                        {
                                p++;
                                position = 1;   //A between P and T
                        }
                        else if (ch == 'T')
                        {
                                t++;
                                position = 2;   //A is back of T
                        }
                        else if (ch == 'A')
                        {
                                a++;
                        }
                        else
                        {
                                flag = 0;
                                break;
                        }

                        switch (position)
                        {
                        case 0:count0++; break;
                        case 1:if (ch != 'P') count1++; break;
                        case 2:if (ch != 'T') count2++; break;
                        }
                }

                if (flag && p==1 && t==1 && (a != 0) && (count0 * count1 == count2))
                {
                        result = 1;
                }
        }

        for (i = 0; i < n; i++)
        {
                if (result)
                {
                        printf("YES\n");
                }
                else
                {
                        printf("NO\n");
                }
        }

        return 0;
}

我最后只能输入六个字符串,找了好半天不知道是哪里错了,麻烦各位大神帮忙debug一下

wp231957 发表于 2021-5-2 07:03:37

上一贴你都没解释第⑤个和第八个为啥是错的
又重复发贴
告诉你,重复发贴不但没用,反而容易招来反感

Christopher. 发表于 2021-5-2 17:28:52

wp231957 发表于 2021-5-2 07:03
上一贴你都没解释第⑤个和第八个为啥是错的
又重复发贴
告诉你,重复发贴不但没用,反而容易招来反感

大哥,我给你解释了啊,我说规律判断错了,具体解释的话就是正确的规律应该是,p之前的A*p和t之间的A=T后面的A的数量,才是正确的

wp231957 发表于 2021-5-2 17:31:09

Christopher. 发表于 2021-5-2 17:28
大哥,我给你解释了啊,我说规律判断错了,具体解释的话就是正确的规律应该是,p之前的A*p和t之间的A=T后 ...

那这个为啥又正确呢
AAPAATAAAA

Christopher. 发表于 2021-5-2 17:31:25

wp231957 发表于 2021-5-2 07:03
上一贴你都没解释第⑤个和第八个为啥是错的
又重复发贴
告诉你,重复发贴不但没用,反而容易招来反感

可能招你反感了,也可能是没有回答你的问题,抑或是说你也不知道这题是怎么回事,但是,你不想回答可以不回答,我也可以自己琢磨,没必要在这当圣母,你回不回答是你的权力,我回不回答你也同样是我的权利,请你有时间帮别人多看两道题,当然不用看我的,别在这当上帝

wp231957 发表于 2021-5-2 17:32:07

Christopher. 发表于 2021-5-2 17:31
可能招你反感了,也可能是没有回答你的问题,抑或是说你也不知道这题是怎么回事,但是,你不想回答可以不 ...

你牛

Christopher. 发表于 2021-5-2 17:33:22

wp231957 发表于 2021-5-2 17:31
那这个为啥又正确呢
AAPAATAAAA

2*2!=4?

Christopher. 发表于 2021-5-2 17:34:04

Christopher. 发表于 2021-5-2 17:33
2*2!=4?

P前面有两个A,P,T中间有两个A,T后面有四个A,满足2*2=4

Christopher. 发表于 2021-5-2 17:35:56

wp231957 发表于 2021-5-2 17:32
你牛

我是垃圾,也正因为我太垃圾,才会在这和你喋喋不休

人造人 发表于 2021-5-2 18:09:36

这两行是怎么回事?

人造人 发表于 2021-5-2 18:55:11

你的代码有两个语法问题,所以逻辑问题我就没有看
我自己写了一个给你参考
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

bool a(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return ch == ch_next;
}

bool b(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return ch == ch_next;
}

bool c(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return ch == ch_next;
}

bool P(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'P') ++count;
    ungetc(ch, stdin);
    return count == 1 ? (ch == ch_next) : false;
}

bool A(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return count == 1 ? (ch == ch_next) : false;
}

bool T(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'T') ++count;
    ungetc(ch, stdin);
    return count == 1 ? (ch == ch_next) : false;
}

int main(void) {
    size_t n;
    char ch;
    scanf("%lu", &n);
    while(scanf("%c", &ch), ch != '\n');
    bool result;
    memset(result, false, sizeof(bool) * n);
    for(size_t i = 0; i < n; ++i) {
      if(a('T')) result = true;
      if(P('A')) result = true;
      if(b('A')) result = true;
      if(A('T')) result = true;
      if(T(-1)) result = true;
      if(c(-1)) result = true;
      if(a(-1)) result = true;
      while(scanf("%c", &ch), ch != '\n');
    }
    for(size_t i = 0; i < n; ++i) {
      result ? puts("YES") : puts("NO");
    }
    return 0;
}


8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
YES
YES
YES
YES
NO
NO
NO
YES


有一个问题,APAAATAA 这个为什么输出的是 NO
aPbATca 这个规则中的b可以是0个或多个A,应该输出YES吧?

人造人 发表于 2021-5-2 19:15:19

我发现上面的代码有一个逻辑问题,不应该设置true,应该是默认true,设置false
这一次最后一个输出的是 NO,有点奇怪,我再研究研究
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

bool a(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return ch == ch_next;
}

bool b(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return ch == ch_next;
}

bool c(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return ch == ch_next;
}

bool P(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'P') ++count;
    ungetc(ch, stdin);
    return count == 1 ? (ch == ch_next) : false;
}

bool A(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'A') ++count;
    ungetc(ch, stdin);
    return count == 1 ? (ch == ch_next) : false;
}

bool T(int ch_next) {
    char ch;
    size_t count = 0;
    while(scanf("%c", &ch), ch == 'T') ++count;
    ungetc(ch, stdin);
    return count == 1 ? (ch == ch_next) : false;
}

int main(void) {
    size_t n;
    char ch;
    scanf("%lu", &n);
    while(scanf("%c", &ch), ch != '\n');
    bool result;
    for(size_t i = 0; i < n; ++i) result = true;
    for(size_t i = 0; i < n; ++i) {
      do {
            if((result = a('T')) == false) break;
            if((result = P('A')) == false) break;
            if((result = b('A')) == false) break;
            if((result = A('T')) == false) break;
            if((result = T(EOF)) == false) break;
            if((result = c(EOF)) == false) break;
            if((result = a(EOF)) == false) break;
      } while(0);
      while(scanf("%c", &ch), ch != '\n');
    }
    for(size_t i = 0; i < n; ++i) {
      result ? puts("YES") : puts("NO");
    }
    return 0;
}


8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA
NO
NO
NO
NO
NO
NO
NO
NO

人造人 发表于 2021-5-2 19:20:19

P和T中间有几个A?我的理解是1个或多个

Christopher. 发表于 2021-5-2 19:31:02

人造人 发表于 2021-5-2 19:20
P和T中间有几个A?我的理解是1个或多个

要是前后都没有的A的话,可以有大于0个,你的理解是正确的

Christopher. 发表于 2021-5-2 19:32:23

#include<stdio.h>

int main(void)
{
        int n;
        int i;
        int result = {0};
    char ch;

        scanf("%d", &n);
    getchar();

        for (i = 0; i < n; i++)
        {
                int p = 0, t = 0, a = 0;
                int flag = 1;   //judge if p a t
                int count0 = 0, count1 = 0, count2 = 0;   //the number of A of different position
                int position = 0;       //the position of A,initial 0,front of P

                while ((ch = getchar()) != '\n')
                {
                        if (ch == 'P')
                        {
                                p++;
                                position = 1;   //A between P and T
                        }
                        else if (ch == 'T')
                        {
                                t++;
                                position = 2;   //A is back of T
                        }
                        else if (ch == 'A')
                        {
                                a++;
                        }
                        else
                        {
                                flag = 0;
                        }

                        switch (position)
                        {
                        case 0:count0++; break;
                        case 1:if (ch != 'P') count1++; break;
                        case 2:if (ch != 'T') count2++; break;
                        }
                }

                if (flag && p==1 && t==1 && (a != 0) && (count0 * count1 == count2))
                {
                        result = 1;
                }
        }

        for (i = 0; i < n; i++)
        {
                if (result)
                {
                        printf("YES\n");
                }
                else
                {
                        printf("NO\n");
                }
        }

        return 0;
}

Christopher. 发表于 2021-5-2 19:34:04

最后我改出来了,是flag判断的那个地方,不能有break,否则的话,跳出循环,后面输入的被视为下一组输入,表达能力有限,见谅见谅

Christopher. 发表于 2021-5-2 19:35:09

人造人 发表于 2021-5-2 19:15
我发现上面的代码有一个逻辑问题,不应该设置true,应该是默认true,设置false
这一次最后一个输出的是 NO ...

谢谢你啦

Christopher. 发表于 2021-5-2 19:36:12

人造人 发表于 2021-5-2 18:55
你的代码有两个语法问题,所以逻辑问题我就没有看
我自己写了一个给你参考



这个规律就是我上面说的那个,你可以把他给的例子带入,我的那个公式是完全符合的

Christopher. 发表于 2021-5-2 19:38:57

人造人 发表于 2021-5-2 18:09
这两行是怎么回事?

抱歉,这个是笔误,不好意思(笑哭)

人造人 发表于 2021-5-2 22:34:37

我也改完了,这是最终版本
具体实现思路可以参考编译原理中的递归下降分析算法
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

/*
* aPbATca
* aPAbTc
* a: (first: ('A', '\0'), follow: ('P'))
* P: (first: ('P'), follow: ('A'))
* A: (first: ('A'), follow: ('A', 'T'))
* b: (first: ('A', '\0'), follow: ('T'))
* T: (first: ('T'), follow: ('A', '\n'))
* c: (first: ('A', '\0'), follow: ('\n'))
*/

bool exist(int ch, int data[], size_t size) {
    for(size_t i = 0; i < size; ++i) {
      if(ch == data) return true;
    }
    return false;
}

bool a(int first[], size_t first_size, int follow[], size_t follow_size, size_t depth) {
    int ch = getchar();
    if(exist(ch, first, first_size)) {
      return a(first, first_size, follow, follow_size, depth + 1);
    }
    if(depth == 0) {
      if(!exist('\0', first, first_size)) return false;
    }
    if(!exist(ch, follow, follow_size)) return false;
    ungetc(ch, stdin);
    return true;
}

bool P(int first[], size_t first_size, int follow[], size_t follow_size, size_t depth) {
    if(depth == 2) return false;
    int ch = getchar();
    if(exist(ch, first, first_size)) {
      return a(first, first_size, follow, follow_size, depth + 1);
    }
    if(depth == 0) {
      if(!exist('\0', first, first_size)) return false;
    }
    if(!exist(ch, follow, follow_size)) return false;
    ungetc(ch, stdin);
    return true;
}

bool A(int first[], size_t first_size, int follow[], size_t follow_size, size_t depth) {
    if(depth == 2) return false;
    int ch = getchar();
    if(exist(ch, first, first_size)) {
      return a(first, first_size, follow, follow_size, depth + 1);
    }
    if(depth == 0) {
      if(!exist('\0', first, first_size)) return false;
    }
    if(!exist(ch, follow, follow_size)) return false;
    ungetc(ch, stdin);
    return true;
}

bool b(int first[], size_t first_size, int follow[], size_t follow_size, size_t depth) {
    int ch = getchar();
    if(exist(ch, first, first_size)) {
      return a(first, first_size, follow, follow_size, depth + 1);
    }
    if(depth == 0) {
      if(!exist('\0', first, first_size)) return false;
    }
    if(!exist(ch, follow, follow_size)) return false;
    ungetc(ch, stdin);
    return true;
}

bool T(int first[], size_t first_size, int follow[], size_t follow_size, size_t depth) {
    if(depth == 2) return false;
    int ch = getchar();
    if(exist(ch, first, first_size)) {
      return a(first, first_size, follow, follow_size, depth + 1);
    }
    if(depth == 0) {
      if(!exist('\0', first, first_size)) return false;
    }
    if(!exist(ch, follow, follow_size)) return false;
    ungetc(ch, stdin);
    return true;
}

bool c(int first[], size_t first_size, int follow[], size_t follow_size, size_t depth) {
    int ch = getchar();
    if(exist(ch, first, first_size)) {
      return a(first, first_size, follow, follow_size, depth + 1);
    }
    if(depth == 0) {
      if(!exist('\0', first, first_size)) return false;
    }
    if(!exist(ch, follow, follow_size)) return false;
    ungetc(ch, stdin);
    return true;
}

int main(void) {
    size_t n;
    char ch;
    scanf("%lu", &n);
    while(scanf("%c", &ch), ch != '\n');
    bool result;
    for(size_t i = 0; i < n; ++i) result = true;
    for(size_t i = 0; i < n; ++i) {
      do {
            if((result = a((int []){'A', '\0'}, 2, (int []){'P'}, 1, 0)) == false) break;
            if((result = P((int []){'P'}, 1, (int []){'A'}, 1, 0)) == false) break;
            if((result = A((int []){'A'}, 1, (int []){'A', 'T'}, 2, 0)) == false) break;
            if((result = b((int []){'A', '\0'}, 2, (int []){'T'}, 1, 0)) == false) break;
            if((result = T((int []){'T', '\0'}, 2, (int []){'A', '\n'}, 2, 0)) == false) break;
            if((result = c((int []){'A', '\0'}, 2, (int []){'\n'}, 1, 0)) == false) break;
      } while(0);
      while(scanf("%c", &ch), ch != '\n');
    }
    for(size_t i = 0; i < n; ++i) {
      result ? puts("YES") : puts("NO");
    }
    return 0;
}
页: [1] 2
查看完整版本: 请各位大神帮忙看下我的代码哪里有问题