PAT乙級1003

1003 我要經過! (20分)

題目地址: https://pintia.cn/problem-sets/994805260223102976/problems/994805323154440192ios

答案正確」是自動判題系統給出的最使人歡喜的回覆。本題屬於 PAT 的「答案正確」大派送 —— 只要讀入的字符串知足下列條件,系統就輸出「答案正確」,不然輸出「答案錯誤」。測試

獲得「答案正確」的條件是:spa

  1. 字符串中必須僅有 PAT這三種字符,不能夠包含其它字符;
  2. 任意形如 xPATx 的字符串均可以得到「答案正確」,其中 x 或者是空字符串,或者是僅由字母 A 組成的字符串;
  3. 若是 aPbTc 是正確的,那麼 aPbATca 也是正確的,其中 abc 均或者是空字符串,或者是僅由字母 A 組成的字符串。

如今就請你爲 PAT 寫一個自動裁判程序,斷定哪些字符串是能夠得到「答案正確」的。code

輸入格式:

每一個測試輸入包含 1 個測試用例。第 1 行給出一個正整數 n (<10),是須要檢測的字符串個數。接下來每一個字符串佔一行,字符串長度不超過 100,且不包含空格。遞歸

輸出格式:

每一個字符串的檢測結果佔一行,若是該字符串能夠得到「答案正確」,則輸出 YES,不然輸出 NOci

輸入樣例

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

輸出樣例

YES
YES
YES
YES
NO
NO
NO
NO

個人理解

這個符合條件的PAT字符串主要是有一個遞歸的嵌套,本身寫兩個看看就知道了。字符串必須所有由P、A、T組成。我分了三類。字符串

  1. I類。起始爲P,中間任意數量的A,結束爲T。PAT、PAAT、PAAAT、PA...AT。
  2. II類。P和T之間只有一個A,兩邊有相同數量的A。APATA、AAPATAA、AAAPATAAA、A...APATA...A。
  3. III類。P和T之間不止一個A,兩邊的A的數量也不相同,可是符合P左邊A的數量 乘以 P和T之間A的數量 等於 P右邊的數量也符合條件。

代碼段

#include <iostream>
#include <string>
using namespace std;
int main() {
    int n = 0;
    cin >> n;
    string pats[n];
    for (int i = 0; i < n; i++) {
        cin >> pats[i];
    }
    for (int i = 0; i < n; i++) {
        string isRight = "NO";
        int pPosition = pats[i].find("PA");
        int tPosition = pats[i].find("AT");  // 實則爲T位置前A的index
        // 若是PA 出如今AT以後,表示不符合規則
        if (pPosition >= tPosition) {
            cout << isRight << endl;
            continue;
        }
        // 判斷P 和 T 之間是否所有爲A
        bool isAllA = true;
        for (int j = pPosition + 1; j <= tPosition; j++) {
            if (pats[i][j] != 'A') {
                cout << isRight << endl;
                isAllA = false;
                break;
            }
        }
        if (!isAllA) {
            continue;
        }
        /*
        * I 類
        * 首先是PAT是符合條件的
        * 根據條件3,若是aPbTc是符合條件的,則aPbATca也符合條件
        * 此時不要求a、b、c徹底相等
        * 當a = '',b = 'A',c = ''時, 一層層衍生出 
        * PAAT  --->    PAAAT   --->    PA...AT
        */
        // 若是P和T兩邊都爲空,則符合條件 例如:PAT、PAAT、PAAAT、PA...AT,均符合條件
        if (pPosition == 0 && tPosition == (pats[i].length() - 2)) {
            cout << "YES" << endl;
            continue;
        } else {
            // P 和 T 之間A的個數僅有一個時
            int aCounter = tPosition - pPosition;
            if (aCounter == 1) {
                /*
                * II 類
                * 首先PAT是符合條件的
                * 根據條件2,若是xPATx也是符合條件的,x爲'', 或者爲僅有A組成的字符串,
                * 由此衍生出
                * APATA --->    AAPATAA --->    AAAPATAAA   --->    A...APATA...A
                */
                // P和T之間只有一個A時,判斷左右兩邊位數是否同樣,且全爲A,例如:APATA、AAPATAA、AAAPATAAA、A...APATA...A
                if (pPosition == (pats[i].length() - tPosition - 2)) {
                    bool flag = true;
                    // P左邊是否全爲A
                    for (int j = 0; j < pPosition; j++) {
                        if (pats[i][j] != 'A') {
                            flag = false;
                            break;
                        }
                    }
                    // T右邊是否全爲A
                    for (int j = pats[i].length() - 1; j > tPosition + 1; j--) {
                        if (pats[i][j] != 'A') {
                            flag = false;
                            break;
                        }
                    }
                    // 位數相同且所有爲A
                    if (flag) {
                        cout << "YES" << endl;
                    } else {
                        cout << isRight << endl;
                    }
                } else {
                    cout << isRight << endl;
                }
                /* 
                * III 類
                * 根據條件3,若是aPbTc是符合條件的,則aPbATca也符合條件
                * 此時不要求a、b、c徹底相等
                * 根據II類的字符串
                * 由APATA一層層衍生出 (此時 a = 'A', b = 'A', c = 'A')
                *   aPbTc       --->        aPbATca
                *   APATA       --->        APAATAA
                *   APAATAA     --->        APAAATAAA
                * 
                * 由AAPATAA一層層衍生出 (此時 a = 'AA', b = 'A', c = 'AA')
                *   aPbTc       --->        aPbATca
                *   AAPATAA     --->        AAPAATAAAA
                *   AAPAATAAAA  --->        AAPAAATAAAAAA
                */
                //P和T之間不止一個A時
            } else {
                bool flag = true;
                // P左邊是否全爲A
                for (int j = 0; j < pPosition; j++) {
                    if (pats[i][j] != 'A') {
                        flag = false;
                        break;
                    }
                }
                if (!flag) {
                    cout << isRight << endl;
                    continue;
                }
                // T右邊是否全爲A
                for (int j = pats[i].length() - 1; j > tPosition + 1; j--) {
                    if (pats[i][j] != 'A') {
                        flag = false;
                        break;
                    }
                }
                // 位數相同且所有爲A
                if (!flag) {
                    cout << isRight << endl;
                    continue;
                }
                // 漸漸發現,只要P左邊A的數量 乘以 P和T之間A的數量 等於 P右邊的數量也符合條件,即第III類
                int leftANumber = pPosition;
                int rightANumber = pats[i].length() - tPosition - 2;
                if (leftANumber * aCounter == rightANumber) {
                    cout << "YES" << endl;
                } else {
                    cout << isRight << endl;
                }
            }
        }
    }
    return 0;
}
相關文章
相關標籤/搜索