題目來源html
「答案正確」是自動判題系統給出的最使人歡喜的回覆。本題屬於 PAT 的「答案正確」大派送 —— 只要讀入的字符串知足下列條件,系統就輸出「答案正確」,不然輸出「答案錯誤」。ios
獲得「答案正確」的條件是:ide
P
、 A
、 T
這三種字符,不能夠包含其它字符;xPATx
的字符串均可以得到「答案正確」,其中 x
或者是空字符串,或者是僅由字母 A
組成的字符串;aPbTc
是正確的,那麼 aPbATca
也是正確的,其中 a
、 b
、 c
均或者是空字符串,或者是僅由字母 A
組成的字符串。如今就請你爲 PAT 寫一個自動裁判程序,斷定哪些字符串是能夠得到「答案正確」的。函數
每一個測試輸入包含 1 個測試用例。第 1 行給出一個正整數 n < 10,是須要檢測的字符串個數。接下來每一個字符串佔一行,字符串長度不超過 100,且不包含空格。測試
每一個字符串的檢測結果佔一行,若是該字符串能夠得到「答案正確」,則輸出 YES
,不然輸出 NO
。spa
8 PAT PAAT AAPATAA AAPAATAAAA xPATx PT Whatever APAAATAA
YES YES YES YES NO NO NO NO
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 是 C++ 的STL容器,內部實現是紅黑樹(一種非嚴格意義的平衡二叉樹,具備排序功能), map 提供一對一的關係code
map<K, T> 類模板定義在頭文件 map 中,它定義了一個保存 T 類型對象的 map, 每一個 T 類對象都有一個關聯的K類型的鍵。 htm
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的函數
思路:
將 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