板栗說算法 之 PAT 乙級 1003 我要通過!(全方面解析)

 

一、題目

答案正確”是自動判題系統給出的最令人歡喜的回覆。本題屬於 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

二、思路 

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

//入門條件是要有P和T,如果沒有就直接no
if(name.find('P') != string::npos && name.find('T') != string::npos)
{
}else{
    cout << "NO" << endl;
}

2.尋找規律

PAT
PAAT
AAPATAA
AAPAATAAAA

//都是正確的

我們已經將P和T的條件準備完成了,最後剩下最爲關鍵的A了

我們可以將aPbTc分爲三塊,1.P前面的 2.P到T的 3.T後面的,分別計數

之後會發現PAT的構造

1(P前面的有幾個數):0 

2(P到T有幾個數):1

3(T後面的有幾個數):0

 

PAAT

1(P前面的有幾個數):0 

2(P到T有幾個數):2

3(T後面的有幾個數):0

 

AAPATAA

1(P前面的有幾個數):2

2(P到T有幾個數):1

3(T後面的有幾個數):2

 

AAPAATAAAA

1(P前面的有幾個數):2

2(P到T有幾個數):2

3(T後幾個數):4

隨後計算規律可得:(P前面的有幾個數)* (P到T有幾個數) = (T後幾個數);

找到規律就好辦了

分別計數之後進行判斷是否(P前面的有幾個數)* (P到T有幾個數) = (T後幾個數);

即可。

3.最後判斷是否都爲'A'

這裏使用count(),C++標準模板庫函數,用於統計某一值在一定範圍內出現的次數。

 

頭文件:#include <algorithm>

if(count(name.begin(),name.end(),'A') != name.size() - 2)
{
   temp = 0;
};

4.解決BUG

下代碼完成後我使用案例PT,輸出爲正確,這顯然是不對的。

PT

P前面的數有0個;

P到T的數有0個;

T後面的數有0個;

這在我們的判斷中是對的

(P前面的有幾個數)* (P到T有幾個數) = (T後幾個數);

0*0=0;

但是這不符合字符串中必須僅有 P、 A、 T這三種字符的標準。

所以我將P到T之間如果有0個的話輸出爲“NO”;

 //num_3爲P到T之間有幾個
 if(num_3 == 0)
{
   cout << "NO" << endl;
}

三、代碼實現

#include <iostream>
using namespace std;

#include <string>

//ccount頭文件
#include <algorithm>
int main()
{
    //用戶輸入
    int num;
    cin >> num;
    
    //循環輸入進行判斷
    for(int i = 0; i < num; i++)
    {
        //讀取輸u入
        string name;
        cin >> name;
        
        //如果字符串中沒有P和T則NO
        if(name.find('P') != string::npos && name.find('T') != string::npos)
        {
            //用於判斷的臨時變量,默認爲真
            int temp = 1;
            
            //記錄‘P’前面的個數
            int num_1 = name.find('P');
            
            //記錄‘T’後面的s個數
            int num_2 = name.size() - name.find('T') -1;
            
            //記錄'P'到'T'之間的個數
            int num_3 = name.find('T') - num_1 - 1;

            //如果'P'到'T'之間的個數爲0的話輸出NO
            if(num_3 == 0)
            {
                cout << "NO" << endl;
            }
            
            //如果u符合規律的話進入下一步f判斷
            else if(num_1 * num_3 == num_2)
            {
                //判斷除了'P'和'T'之外的字母是否爲’A‘,不爲A則temp=0
                if(count(name.begin(),name.end(),'A') != name.size() - 2)
                {
                    temp = 0;
                };
                
                //最後判斷該字符串是否是所需要的
                if(temp == 1)
                {
                    cout << "YES" << endl;
                }else{
                    cout << "NO" << endl;
                }
            }else{
                //如果不符合規律就輸出NO
                cout << "NO" << endl;
            }
        }else{
            //如果沒有P和T就輸出NO
            cout << "NO" << endl;
        }
    }
}

如果有所幫助的話,記得點個關注喲,每天更新博客,一同進步!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章