PAT 乙級 1003.我要經過! C++/Java

1003 我要經過! (20 分)

題目來源html

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

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

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

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

輸入格式:

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

輸出格式:

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

輸入樣例:

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

輸出樣例:

YES
YES
YES
YES
NO
NO
NO
NO

分析:

  • 只能有一個P一個T
  • 對於 xPATx,PAT, AAPATAA都是YES,只要兩端的 A 的個數相同
  • 對於aPbTc和aPbATca,
    • PAT是正確的,那麼PAAT也是正確的
    • AAPATAA是正確的,那麼AAPAATAAAA也是正確的
  • 總結:只能有一個P和T,前面A的個數 * 中間A的個數 = 後面A的個數
  • 能夠用三個變量,front,mid,rear將每一個部分的A的個數記錄下來,最後判斷front * mid是否等於rear
 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 bool pass(string str)
 6 {
 7     if (str == "PAT")
 8     {
 9         return true;
10     }
11     
12     int index, front, mid, rear;
13     index = front = mid = rear = 0;
14 
15     
16     while (str[index] == 'A')
17     {
18         index++;
19         front++;    //記錄前面A的個數
20     }
21     if (str[index] == 'P')
22     {
23         index++;
24     }
25     else
26     {
27         return false;
28     }
29 
30     while (str[index] == 'A')
31     {
32         mid++;    //記錄中間A的個數
33         index++;    
34     }
35 
36     if (str[index] == 'T')
37     {
38         index++;
39     }
40     else
41     {
42         return false;
43     }
44 
45     while (str[index] == 'A')
46     {
47         rear++;    //記錄後面A的個數
48         index++;
49     }
50 
51     if (!str[index] && rear == mid * front && mid > 0)
52     {
53         return true;
54     }
55     
56     return false;
57 }
58 
59 int main()
60 {
61     int n;
62     string str;
63     cin >> n;
64 
65     for (int i = 0; i < n; ++i)
66     {
67         cin >> str;
68         bool flag = pass(str);
69         if (flag)
70         {
71             cout << "YES" << endl;
72         }
73         else
74         {
75             cout << "NO" << endl;
76         }
77     }
78 
79     return 0;
80 }

 

map解法:

首先了解下 map 是什麼, map  是 C++ 的STL容器,內部實現是紅黑樹(一種非嚴格意義的平衡二叉樹,具備排序功能), map 提供一對一的關係code

 map<K, T> 類模板定義在頭文件 map 中,它定義了一個保存 T 類型對象的 map, 每一個 T 類對象都有一個關聯的K類型的鍵 htm

map的特性:對象

  • 全部的元素會根據元素的鍵值(key)自動排序
  • map全部元素都是pair,同時擁有key(鍵值)和value(實值)
  • pair的第一個元素視爲鍵值key,第二個元素視爲實值value
  • map不容許兩個元素擁有相同的鍵值

map的基本構造函數blog

map<int ,string >intMap;

map<string , int >strMap;        

map< char ,string>charMap;

map<sring, char>strMap;        

map<char ,int>charMap;           

map<int ,char >intMap;

map的基本操做函數

      begin()          返回指向map頭部的迭代器

      clear()         刪除全部元素

      count()          返回指定元素出現的次數

      empty()          若是map爲空則返回true

      end()            返回指向map末尾的迭代器

      equal_range()    返回特殊條目的迭代器對

      erase()          刪除一個元素

      find()           查找一個元素

      get_allocator()  返回map的配置器

      insert()         插入元素

      key_comp()       返回比較元素key的函數

      lower_bound()    返回鍵值>=給定元素的第一個位置

      max_size()       返回能夠容納的最大元素個數

      rbegin()         返回一個指向map尾部的逆向迭代器

      rend()           返回一個指向map頭部的逆向迭代器

      size()           返回map中元素的個數

      swap()            交換兩個map

      upper_bound()     返回鍵值>給定元素的第一個位置

      value_comp()      返回比較元素value的函數
View Code

 

思路:

將 P, A, T 三個字符做爲鍵值存入map,對應的value是它們出現的次數,最後還要判斷 map.size()是否等於3

 

 1 #include <iostream>
 2 #include <string>
 3 #include <map>
 4 using namespace std;
 5 
 6 bool pass(string str)
 7 {
 8     map<char, int> charMap;
 9     int length = str.size();
10     int posOfP = 0, posOfT = 0;
11     for (int i = 0; i < length; ++i)
12     {
13         charMap[str[i]]++;
14         if (str[i] == 'P')
15         {
16             posOfP = i;    //這時候的i爲P前面 A 的個數(執行完循環體的步驟纔會執行++i)也能夠理解爲P的位置
17         }
18         if (str[i] == 'T')
19         {
20             posOfT = i;    //i爲T的位置
21         }
22     }
23     if (charMap['P'] == 1 && charMap['T'] == 1 && charMap['A'] != 0 && charMap.size() == 3 && posOfT - posOfP != 1 && posOfP*(posOfT - posOfP - 1) == str.size() - posOfT - 1)
24     {
25         return true;
26     }
27     else
28     {
29         return false;
30     }
31 }
32 
33 
34 int main()
35 {
36     int n;
37     string str;
38     cin >> n;
39 
40     for (int i = 0; i < n; ++i)
41     {
42         cin >> str;
43         bool flag = pass(str);
44         if (flag)
45         {
46             cout << "YES" << endl;
47         }
48         else
49         {
50             cout << "NO" << endl;
51         }
52     }
53     return 0;
54 }

 

23行代碼:

if (charMap['P'] == 1 && charMap['T'] == 1 && charMap['A'] != 0 && charMap.size() == 3 && posOfT - posOfP != 1 && posOfP*(posOfT - posOfP - 1) == str.size() - posOfT - 1)
charMap['P'] == 1 && charMap['T'] == 1 && charMap['A'] != 0 && charMap.size() == 3

爲了防止出現`PT` 或 P和T個數大於1的狀況
而charMap.size() == 3 是爲了防止出現除 PAT 以外的字母

 

posOfT - posOfP != 1 && posOfP*(posOfT - posOfP - 1) == str.size() - posOfT - 1)
1.假設給定字符串是AAPATAA,那麼posOfT = 4, posOfP = 2, posOfT - posOfP = 2,因此,中間A的個數 = posOfT - posOfP - 1
2.假設給定字符串是PT,那麼 posOfT - posOfP = 1,因此posOfT - posOfP != 1是用來排除PT這種中間沒有A的狀況的
3.假設給定字符串是AAPATAA,那麼str.size() = 7, posOfT = 4, str.size() - posOfT - 1 = 後面A的個數

知足上述條件就返回 true

相關文章
相關標籤/搜索