pat乙级 1003 题解

思维难度与编码难度依旧不大,但却被这题折磨了一天多,难点与关键点在于读懂题目所给的三个条件并用代码翻译出来

一、整体思路:

1.数据结构上,采用二维数组存储输入的n个字符串,使用全局int数组存储各字符串的正确与错误的判断情况

2.总体思路上,题目给出的1、2两个条件较为简单,而第3个条件是第2个条件的延伸与拓展,相对比较复杂,因此选择先使用1、2两个条件对字符串进行筛选,经过筛选后依然不能确定是正确或者错误的字符串再交由条件3进行判断以节省时间

二、关键问题:

1.条件2应如何翻译

2.条件3是什么意思,应如何翻译,这是本题的难点与关键点所在

三、关键问题对应的解决方法:

1.在字符串中检索是否出现PAT的字符序列,当出现该字符序列时,判断其左右两边的式子是否满足以下两种情况:

a.该字符串就为PAT,即该字符序列左右两边为空字符(P为该字符串起点且T后为\0字符)

b.该字符序列左右两边的式子相同且仅含A,即左右两边的式子仅含A且A的个数相等

2.初看条件3有些吓人,其是在条件2的基础上不停迭代,以为需要用到递归之类的复杂结构,其实不然,通过列举几个最简单的正确的初始字符串做推导,再结合条件3的表述找出其中所蕴藏的规律即相应的数学表达式就很容易用代码对条件3进行翻译了

a.初始正确字符串为PAT,由此推导出的正确式子有PAAT   PAAAT...

b.初始正确字符串为APATA,由此推导出的正确式子有APAATAA   APAAATAAA

c.初始正确字符串为AAPATAA,由此推导出的正确式子有AAPAATAAAA   AAPAAATAAAAAA

以上式子还是可以分为条件2中的两种情况

a.以字符序列PA开头,其后面的字符为A或T,且当检索到T时,其一定为字符串末尾,其后一定为\0字符

b.检索到PA...T的字符序列,P与T之间全为A,且PA...T之间每增加1个A,Tx...后就增加1个P之前的字符序列x(该序列必须全为A),翻译一下就是,T之后的A字符个数=P之前的A字符个数+PA...T之间增加的A字符个数*P之前的A字符个数

四、一些小细节:

1.=与==傻傻分不清楚,某些情况下编译不会报错,而运行结果却是大错特错

2./字符与\字符傻傻分不清楚

代码如下:

#define _CRT_NONSTDC_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int judge_flag[100];

void judge_1(char string[100], int n);
void judge_2(char string[100], int n);
void judge_3(char string[100], int n);
int is_only_equal_A(int p,char string[100]);
int data_verification(int p,int t,int A_in_P_T,char string[100]);

int main()
{
    int n;
    scanf("%d", &n);

    char string[10][100];
    int i;

    for (i = 0; i < n; i++)
    {
        judge_flag[i]=-1;

        scanf("%s", string[i]);


        judge_1(string[i], i);

        if (judge_flag[i] != 0)
        judge_2(string[i], i);

        if (judge_flag[i] == -1)
        judge_3(string[i], i);


        if (judge_flag[i] == 1)
        printf("YES");
        else
        printf("NO");

        if (i != n - 1)
        printf("\n");                     
    }
}

void judge_1(char string[100], int n)
{
    int i;
    for (i = 0; string[i]; i++)
    {
        if (!(string[i] == 'P' || string[i] == 'A' || string[i] == 'T'))
        {
            judge_flag[n] = 0;
            break;
        }
    }
}

void judge_2(char string[100], int n)
{
    if(string[0]=='P'&&string[1]=='A'&&string[2]=='T'&&string[3]=='\0')
    judge_flag[n] = 1;

    int i;
    for (i = 0; string[i]; i++)
    {
        if (string[i] == 'P')
        {
            if (string[i + 1] == 'A' && string[i + 2] == 'T')
            {
                if(is_only_equal_A(i,string))
                {
                    judge_flag[n] = 1;
                    break;
                }
            }
        }
    }
}

void judge_3(char string[100], int n)
{
    int flag = 0;

    int i;
    for (i = 0; string[i]; i++)
    {
        if (string[i] == 'P' && string[i + 1] == 'A')
        {
            int j;
            for (j = 1; string[i + 1 + j] == 'A' || string[i + 1 + j] == 'T'; j++)
            {
                if (string[i + 1 + j] == 'T')
                {
                    if (i == 0 && string[i + 1 + j + 1] == '\0')
                        flag = 1;
                    else
                    {
                        flag = data_verification(i, i + 1 + j, j, string);
                        break;
                    }              
                }
            }
        }
    }
    judge_flag[n] = flag;
}

int is_only_equal_A(int p,char string[100])
{
    int i;
    int left_Acount=0;
    int right_Acount=0;

    for(i=0;i<p;i++)
    {
        if(string[i]=='A')
        left_Acount++;
        else
        return 0;
    }

    for(i=p+3;string[i];i++)
    {
        if(string[i]=='A')
        right_Acount++;
        else
        return 0;
    }

    if(left_Acount!=right_Acount)
    return 0;
    else
    return 1;
}

int data_verification(int p,int t,int A_in_P_T,char string[100])
{
    int i;
    int A_in_P=0;
    int A_inT_=0;

    for(i=0;i<p;i++)
    {
        if(string[i]!='A')
        return 0;
        A_in_P++;
    }

    for(i=t+1;string[i];i++)
    {
        if(string[i]!='A')
        return 0;
        A_inT_++;
    }

    if(A_inT_==A_in_P+(A_in_P_T-1)*A_in_P)
    return 1;
    else
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值