PAT乙级1003 用C语言进行编程

我发现,好久没写算法题了,人都变菜了,对代码的逻辑思维能力也下降了,确实不应该。

PAT乙级才只做到第三题1003的时候,就发现自己已经力不从心,很多都不会了。

还是得好好地反思一下自己。

在做这道题的时候,主要遇到的问题就是,题目没有审清楚,与其说没有审清楚,不如说压根就没看懂题目。

所以,从我个人角度来说,我觉得这道题目最大的难点就在于审题。

话不多说,先来看一看这道题目的要求:

1、字符串中必须有且仅有P、A、T这三种字符,不能包含其它字符。

2、任意形如xPATx的字符串都会输出“答案正确,也就是YES”,其中x可以是空字符串,或者仅仅是由字母A组成的字符串。

3、如果aPbTc是正确的,那么aPbATca也是正确的,这里的a、b、c可以是空字符串,或者是仅由字母A组成的字符串。

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

输出:YES

YES

等等,有多少个字符串就输出多少个YES、YES和NO。

理顺逻辑最为关键,这是这道题最最最难的地方

在拿到一道编程题的时候,最重要的就是要理清逻辑:

1、字符串中必须有且仅有P、A、T,不能包含其它字符,所以只需要判断字母P字母A字母T即可。

2、PAT、APATA都是正确的,其实这里有一个特点很明显,就是字母P和字母T都有且仅有一个,所以,这里要用到计数(PS:这里卡了我好久,正是因为没有第一时间想到要用到计数法,所以一直做不出来)

还有,P前面的字母A数量和T后面的字母A数量相同,当然这是根据要求二所得到的。

3、第三个要求是最难看懂的,我也是想了好久,做了好多,也没想明白,后来去查阅相关资料,然后才明白了,这道题目是不包含空字符的,因为根据第一个条件,空字符不可以存在,所以说,a、b、c三个字母就都是字母A,因为a和c的数量相同,所以a如果是A,那么c就是A,a如果是AA,那么c就是AA,两个是相同的。

然后把这个格式组合起来可以得到:APAATAA,类推一下就是AAPAATAAAA。

很明显,这里有一个格式,就是左边的A数量与中间的A数量相乘可以得到最右边的A数量。

简单的来说,就是这么一个公式:leftA * middleA = rightA

好,根据这些,就不难看出这道题目的逻辑。

接下来就是代码部分。

代码的实现

这也是较为困难的地方,我在做的时候也遇到了不少问题。

首先,要输入一个整数n,这没有疑问,就是准备一个scanf函数,来输入一个整数即可。

然后,接下来输入的字符串数量得在整数n的范围内。

惭愧啊,这么一个简单的问题我都会出错。

其实就是把输入字符串的scanf函数写在for循环里面即可。

    int n = 0;
    scanf("%d", &n); //输入整数
    char s[100];
    for(int i = 0;i < n; i++){
        scanf("%s", s);
}

真的非常简单,我都不知道为什么我会犯这样的错误,反思反思。

然后就是对字母P、字母A、字母T进行计数,其实只需要对字母P、字母T计数即可,不过为了更加清楚,就都写出来了。

        for(int i = 0; i < strlen(s); i++){
            if(s[i] =='P'){
                placeP = i;
                countP++;
            }
            else if(s[i] =='T'){
                placeT = i;
                countT++;
            }
            else if(s[i] == 'A'){
                placeA = i;
                countA++;
            }
            else{
                break;
            }
        }

这个得到之后,接下来就是最为重要也是最难的部分。

也就是进行一定的判断。

怎么样的结果能得到正确也就是YES呢。

毫无疑问,那就是:

1、当字母P和字母T的数量都是1的时候。

2、P左边字母数量等于T右边字母数量的时候。

3、当中间字母数量>0的时候,当字母P左边字母A的数量与字母P和字母T之间的字母A的数量相乘得到字母T右边数量的时候。

要同时满足以上条件,才能够判断是YES。

或者,同时不满足以上条件,判断为NO来的出结果也不是不可以。

所以可以得到:

#include <stdio.h>
#include <string.h>

int main() {
    int n = 0;
    scanf("%d", &n); //输入整数
    char s[100];
    int countP = 0; //对字母P进行计数
    int countT = 0; //对字母T进行计数
    int countA = 0;
    int placeP = 0;
    int placeT = 0;
    int placeA = 0;
    int left_A = 0;
    int middle_A = 0;
    int right_A = 0;
    for(int i = 0;i < n; i++){
        scanf("%s", s);
        for(int i = 0; i < strlen(s); i++){
            if(s[i] =='P'){
                placeP = i;
                countP++;
            }
            else if(s[i] =='T'){
                placeT = i;
                countT++;
            }
            else if(s[i] == 'A'){
                placeA = i;
                countA++;
            }
            else{
                break;
            }
        }
        left_A = placeP;
        middle_A = placeT - placeP - 1;
        right_A = strlen(s) - placeT - 1;
            if(countP == 1 && countT == 1 && middle_A > 0 && left_A * middle_A == right_A ){
                printf("YES\n" );
                continue;
            }
            
                printf("NO\n");
    }
     return 0;
}


经过编译器跑,但是却没有得到我想要的结果,我就觉得很奇怪。

然后提交到PAT网站的时候,也发现了错误,只是部分正确,才拿了4分,惭愧。

修改错误之后的第一版

在认真排查了代码错误之后,我才发现这些变量我都写成了全局变量,那当然会出错了。

真正的问题在于,这些变量不能写成全局变量,因为在for循环内用过一次之后就要直接用到后面去了,而不是再存储。

所以,修改之后,再提交测试,但还是发现了问题,如下图所示。

运行超时了,我之前随便在char s[100]填了一个,后来想想不对,应该填为n,但是溢出导致超时,不应该。

int n = 0;
    scanf("%d", &n); //输入整数
    char s[n];

正确结果

#include <stdio.h>
#include <string.h>

int main() {
    int n = 0;
    scanf("%d", &n); //输入整数
    char s[100];
    for(int i = 0;i < n; i++){
        scanf("%s", s);
        int countP = 0; //对字母P进行计数
        int countT = 0; //对字母T进行计数
        int countA = 0;
        int placeP = 0;
        int placeT = 0;
        int placeA = 0;
        int left_A = 0;
        int middle_A = 0;
        int right_A = 0;
        for(int i = 0; i < strlen(s); i++){
            if(s[i] =='P'){
                placeP = i;
                countP++;
            }
            else if(s[i] =='T'){
                placeT = i;
                countT++;
            }
            else if(s[i] == 'A'){
                placeA = i;
                countA++;
            }
            else{
                break;
            }
        }
        left_A = placeP;
        middle_A = placeT - placeP - 1;
        right_A = strlen(s) - placeT - 1;
            if(countP == 1 && countT == 1 && middle_A > 0 && left_A * middle_A == right_A ){
                printf("YES\n" );
                continue;
            }
            
                printf("NO\n");
    }
     return 0;
}


总结

总的来说,这道题目难度还是有的,或者是我实力比较差,毕竟还在慢慢学C语言,慢慢来吧。

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值