[PAT B] 1003 我要通過! (20 分)

Squ1rrel發表於2019-12-23

題目

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

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

  1. 字串中必須僅有 P、 A、 T這三種字元,不可以包含其它字元;

  2. 任意形如 xPATx 的字串都可以獲得“答案正確”,其中 x 或者是空字串,或者是僅由字母 A 組成的字串;

  3. 如果 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

思路分析

這題我想複雜了,看到條件二 xPATx 不自覺想到正規表示式的反向引用,但是條件三用正則比較複雜,雖然此題 AC 了,但是做的實在是很不漂亮,以後有時間還得重新研究一下。

條件1,2都非常簡單

條件3要難點在於條件是遞迴式的,簡單計算易得, a * b = c

c++ 應該使用 "." 保證轉義,如 .1

正則搜尋迭代器 regex_search() 注意不能用 "A*" 等無底線要求,會無限迭代

最後輸出注意空行 \n

舉一反三

正則雖好,其侷限性也要在考慮範圍內

推薦一本正規表示式的閱讀書籍,我已經看完了,寫的非常好:
精通正規表示式

我這邊有影印版,想要的朋友也可以聯絡我

程式碼

#include <iostream>
#include <regex>
/*注意事項:
 * 條件1,2都非常簡單
 * 條件3要難點在於條件是遞迴式的,簡單計算易得, a * b = c
 * c++ 應該使用 "\\" 保證轉義,如 "\\1"
 * 正則迭代器注意不能用 "A*" 等無底線要求,會無限迭代
 * 最後輸出注意空行 "\n"
 * */
using namespace std;

int num = 0;
string str;
regex regex_1("[P|A|T]+");//滿足條件一
regex regex_2("(A*)PAT\\1");//滿足條件二直接輸出
regex regex_3("A*PA+TA*");//條件三的大前提
regex regex_4("A+");//找到 A 的數量

bool checkString(string str) {
    int i = 0;
    bool r1, r2, r3, r4;
    smatch result;
    string temp[3];
    string::const_iterator iterStart = str.begin();
    string::const_iterator iterEnd = str.end();

    r1 = regex_match(str, regex_1);
    r2 = regex_match(str, regex_2);
    r3 = regex_match(str, regex_3);

    //使用迭代器,將正則匹配到的結果存在 temp[] 裡
    while (regex_search(iterStart, iterEnd, result, regex_4)) {
        temp[i++] = result[0];
        iterStart = result[0].second;
    }

    //滿足 a * b = c
    r4 = ((temp[0].size() * temp[1].size() == temp[2].size()));

    //r1 必須滿足,r2 或 r3 && r4 滿足即可
    if (r1 && (r2 || (r3 && r4))) {
        return true;
    } else return false;
}

int main() {
    cin >> num;
    string arr[num];
    for (int i = 0; i < num; i++) {
        cin >> str;
        if (checkString(str)) {
            arr[i] = "YES";
        } else arr[i] = "NO";
    }
    for (int i = 0; i < num; i++) {
        cout << arr[i] << "\n";
    }

    return 0;
}

辛勞 篤定 輕苦 微甜 ----汪曾祺

相關文章