1. 程式人生 > >1003、我要通過(20分)

1003、我要通過(20分)

題目

“答案正確”是自動判題系統給出的最令人歡喜的回覆。本題屬於PAT的“答案正確”大派送 —— 只要讀入的字串滿足下列條件,系統就輸出“答案正確”,否則輸出“答案錯誤”。

得到“答案正確”的條件是:

  1. 字串中必須僅有P, A, T這三種字元,不可以包含其它字元;
  2. 任意形如 xPATx 的字串都可以獲得“答案正確”,其中 x 或者是空字串,或者是僅由字母 A 組成的字串;
  3. 如果 aPbTc 是正確的,那麼 aPbATca 也是正確的,其中 a, b, c 均或者是空字串,或者是僅由字母 A 組成的字串。
    現在就請你為PAT寫一個自動裁判程式,判定哪些字串是可以獲得“答案正確”的。

輸入格式:

 每個測試輸入包含1個測試用例。第1行給出一個自然數n ,是需要檢測的字串個數。接下來每個字串佔一行,字串長度不超過100,且不包含空格。

輸出格式:每個字串的檢測結果佔一行,如果該字串可以獲得“答案正確”,則輸出YES,否則輸出NO。

輸入樣例:

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

輸出樣例:

YES
YES
YES
YES
NO
NO
NO
NO

題目分析

  • 解題時程式碼並不難,思路也只是略微繁瑣,難點在於讀懂題目
  • 主要看條件1與條件3,條件2是條件3的特殊情況
  • 條件1需要我們,為PAT3個字元設定計數,逐一讀取字元陣列,遇到PAT就計數,不是這3個字母,直接判定NO,此外迴圈結束後,PT兩個字元數量必須是1,A必須大於等於1,即不能等於0
  • 條件3就比較複雜了,首先說一下條件3的意思,小寫字母abc都代表由n個'A'組成的字串,其中n可以為0;再看一下變化量,也就是P和T之間每增加一個'A',其最後方都要增加一個a字串,也就是增加一個和P之前字串相同的量。這麼一說好像沒有說到b字串的事情,但是我們從多到少進行推導發現,b看似是一個初始狀態,但實際上,也是有剛才的規則生成的。這時候看條件2,xPATx就是最原始的狀態了,也就是條件3的特例
  • 下面說一下處理方法,對於條件1,不用再多講,主要說一下對條件3的處理。設定兩個位置變數來記錄第一次出現P和T的位置,從程式碼執行角度看,不需要對“第一次”進行特殊處理,因為只要有第二次,後面肯定就報錯了(PT的數量只能為1)。P的下標也就是P的位置其實就是a字串中'A'的數量,T減去P再減去1,就是PT之間‘A’的數量,len-P-1就是T後面‘A’的數量,只要成乘法關係即滿足。
  • 有一個陷阱,就是P一定要在T的前面,很容易忽視掉。

程式碼

  • C/C++
#include<stdio.h>
#include<string.h>
bool judge(char str[])
{
    int cnt_A = 0,cnt_P = 0,cnt_T = 0;        //儲存PAT3個字母出現的次數
    int lp = -1,lt = -1;           //儲存P和T兩個字母首次出現的位置,如果出現多次的話,後文會判定false的 
    
    for(int i=0;i<strlen(str);i++)
    {
        if(str[i]=='A')
            cnt_A++;
        else if(str[i]=='P')
        {
            cnt_P++;
            lp = i;
        }
        else if(str[i]=='T')
        {
            cnt_T++;
            lt = i;
        }
        else
            return false;        
    }
    if(cnt_T!=1||cnt_T!=1||cnt_A==0||lp>lt)        //判斷是否至少存在一個PAT 
        return false;
    if(lp*(lt-lp-1)!=strlen(str)-lt-1)
        return false;
    return true;    
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        char str[101];
        scanf("%s",str);
        if(judge(str))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}