1. 程式人生 > >【洛谷】訓練場_字符串處理

【洛谷】訓練場_字符串處理

des 另一個 b+ 開頭 利用 count ide 函數 舞蹈

P1071潛伏者

題意:

輸入共三行,每行為一個長度在1到100之間的字符串,第1行為一條加密信息,第2行為第1行的加密信息所對應的原信息,第3行則是要求翻譯的加密信息。比如

第一行:ABA

第二行:ACA

第三行:BA

的情況下,輸入的結果則是 CA

但,還有條件限制,

① :第二行裏A~Z這26個字母一定都出現過

② :加密信息與原文信息不能有重復,比如(密文->原信息)A->A,A->B這樣是不行的

③ :在②的同理下,X->A,Z->A也是不行的

當不符合以上條件之一時,就輸出Failed,否則輸出利用密碼翻譯加密信息後得到的原信息

(分析下3個輸入輸出樣例就很清晰明了了)

分析:

字符一一映射,這時候應該吹一波map大法好了。若對map還不了解的趕緊去學習,超級好用!個人覺得map算是加強版的數組。

如果你會用map,這題已經可以AC一大半了。

我添加了兩個bool數組,一個是判斷密文裏是否已經映射了原信息,另一個是判斷A~Z是否全都出現了。

提交代碼時,洛谷警告了下語法就AC了。

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<map>
 4 #include<string>
 5
#include<cstring> 6 using namespace std; 7 8 string str1, str2, str3; 9 map<char, char> mymap; 10 bool ch[27], have[27]; 11 12 int main() 13 { 14 while(cin >> str1 >> str2 >> str3){ 15 int count = 0; 16 memset(ch, false, sizeof(ch));
17 memset(have, false, sizeof(have)); 18 for(int i = 0; i < str1.size(); i++){ 19 if(!have[str1[i]-A]) { 20 mymap[str1[i]] = str2[i]; 21 have[str1[i]-A] = true; 22 } 23 else break; 24 if(!ch[str2[i]-A]) { count++; ch[str2[i]-A] = true; } 25 } 26 27 if(count != 26) { cout << "Failed" << endl; continue; } 28 else { 29 for(int i = 0; i < str3.size(); i++){ 30 cout << mymap.find(str3[i])->second; 31 } 32 cout << endl; 33 } 34 } 35 return 0; 36 }
AC代碼

下一題:

P1538迎春舞會之數字舞蹈

題意:

輸入一個k表示數的大小,下一行輸入的字符串表示要表演的姿態。

分析:

也許剛看到這個輸出時你跟我一樣一臉懵圈,但只要把輸出樣例復制到記事本上就很清晰了。(如圖)

技術分享圖片

K = 2表示箭頭所指的長度分別為2。

結果分析發現是一道模擬題,需要一點耐心去規劃每一步的輸出。

詳細分析貼在代碼裏:

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 using namespace std;
 5 
 6 string str;
 7 int k;
 8 
 9 int main()
10 {
11     while(cin >> k){
12         cin >> str;
13 
14         // 開始模擬
15         for(int j = 0; j < 2*k + 3; j++){
16             for(int i = 0; i < str.size(); i++){
17                 // k +2 是輸出角落那個空格,如果還不清楚請再研究下輸出樣例
18                 if(j == 0 || j == k+1 || j == 2*k+2){ // 輸出 ‘-‘
19                     // 1,4,7,0 的 ‘-‘輸出部分要特殊處理
20                     if(str[i] != 1 && (str[i] != 4 || j == k+1) && (str[i] != 7 || j == 0) && (str[i] != 0 || j == 0 || j == 2*k+2)){ 
21                         for(int h = 0; h < k+2; h++){
22                             if(h == 0 || h == k+1) cout <<  ;
23                             else cout << -;
24                         }
25                     }
26                     else for(int h = 0; h < k+2; h++) cout <<  ;
27                 }
28 
29                 else { // 輸出 ‘|‘, 分了兩部分,由中間線分開,比如數字 2 的上半部分與下半部分就不一樣, 上半部分相同的就放在一起判斷輸出
30                     if(j < k+1){ // 上半部分
31                         if(str[i] == 1) for(int h = 0; h < k+2; h++){
32                             if(h == k+1) cout << |;
33                             else cout <<  ;
34                         }
35                         else if(str[i] == 2 || str[i] == 3 || str[i] == 7) {
36                             for(int h = 0; h < k+2; h++){
37                                 if(h == k+1) cout << |;
38                                 else cout <<  ;
39                             }
40                         }
41                         else if(str[i] == 5 || str[i] == 6){
42                             for(int h = 0; h < k+2; h++){
43                                 if(h == 0) cout << |;
44                                 else cout <<  ;
45                             }
46                         }
47                         else if(str[i] == 4 || str[i] == 8 || str[i] == 9 || str[i] == 0){
48                             for(int h = 0; h < k+2; h++){
49                                 if(h == 0 || h == k+1) cout << |;
50                                 else cout <<  ;
51                             }
52                         }
53                     }
54                     else if(j > k+1){ // 下半部分,同理
55                         if(str[i] == 1) for(int h = 0; h < k+2; h++) {
56                             if(h == k+1) cout << |;
57                             else cout <<  ;
58                         }
59                         else if(str[i] == 2) {
60                             for(int h = 0; h < k+2; h++){
61                                 if(h == 0) cout << |;
62                                 else cout <<  ;
63                             }
64                         }
65                         else if(str[i] == 3 || str[i] == 4 || str[i] == 5 || str[i] == 7 || str[i] == 9){
66                             for(int h = 0; h < k+2; h++){
67                                 if(h == k+1) cout << |;
68                                 else cout <<  ;
69                             }
70                         }
71                         else if(str[i] == 6 || str[i] == 8 || str[i] == 0){
72                             for(int h = 0; h < k+2; h++){
73                                 if(h == 0 || h == k+1) cout << |;
74                                 else cout <<  ;
75                             }
76                         }
77                     }
78                 }
79                 cout <<  ; // 每輸出完一個數字就空出一格
80             }
81             cout << endl; // 一行數字遍歷完畢,換行繼續輸出
82         }
83     }
84     return 0;
85 }
AC代碼

下一題:

P1603斯諾登密碼

題意:

找到句子裏與數字有關的單詞,平方後排列,輸出排列後最小的數字。

分析:

暴力解決。因為輸入只有6個單詞,所以是可以暴力解決的(笑)

然後再用排序算法把小的放前面,輸出結果去掉開頭的0即可。

註意,個位數前面保留0的這一性質!

技術分享圖片
 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     string cha[7];
 8     string ch[7];
 9     int n = 0;
10     for(int i = 0; i < 7; i++){ // 暴力找出平方後的數字
11         cin >> ch[i];
12         if(ch[i] == ".") break;
13         if(ch[i] == "one" || ch[i] == "a" || ch[i] == "another" || ch[i] == "first")
14             cha[n++] = "01";
15         else if(ch[i] == "two" || ch[i] == "both" || ch[i] == "second") cha[n++] = "04";
16         else if(ch[i] == "three" || ch[i] == "third") cha[n++] = "09";
17         else if(ch[i] == "four") cha[n++] = "16";
18         else if(ch[i] == "five") cha[n++] = "25";
19         else if(ch[i] == "six") cha[n++] = "36";
20         else if(ch[i] == "seven") cha[n++] = "49";
21         else if(ch[i] == "eight") cha[n++] = "64";
22         else if(ch[i] == "nine") cha[n++] = "81";
23         else if(ch[i] == "ten" || ch[i] == "twenty") cha[n++] = "00";
24         else if(ch[i] == "eleven") cha[n++] = "21";
25         else if(ch[i] == "twelve") cha[n++] = "44";
26         else if(ch[i] == "thirteen") cha[n++] = "69";
27         else if(ch[i] == "fourteen") cha[n++] = "96";
28         else if(ch[i] == "fifteen") cha[n++] = "25";
29         else if(ch[i] == "sixteen") cha[n++] = "56";
30         else if(ch[i] == "seventeen") cha[n++] = "89";
31         else if(ch[i] == "eighteen") cha[n++] = "24";
32         else if(ch[i] == "nineteen") cha[n++] = "61";
33     }
34     for(int i = 0; i < n-1; i++) // 排序
35     {
36         for(int j = 0; j < n-1-i; j++)
37         {
38             if(cha[j] > cha[j+1])
39             {
40                 string b = cha[j];
41                 cha[j] = cha[j+1];
42                 cha[j+1] = b;
43             }
44         }
45     }
46     string ans = "";
47     for(int i = 0; i < n; i++)
48     {
49         ans += cha[i];
50     }
51     bool zero = false; // 判斷開頭是否有 0 
52     for(int i = 0; i < n*2; i++) 
53     {
54         if(ans[i] != 0 || zero){ 
55             zero = true;
56             cout << ans[i];
57         }
58         else if(!zero) continue;
59     }
60     if(n == 0) cout << "0\n"; // 當句子裏沒有數字時的特判處理
61     return 0;
62 }
AC代碼

下一題:

P1012拼數

題意:

給一個n,然後再給n個正整數,問這n個數怎麽組拼成的數最大。

分析:

字典序大的數放前面就可以了。

因此可以用一個sort()函數解決,只需要在sort()裏加一個

bool cmp(string a, string b)

{

return a+b > b+a;

}

判斷就ok,簡單清晰。(參考了洛谷作者King_LRL的題解)

當初我做這題的時候還不會用string與sort函數,結果用char[]與冒泡排序解決了,代碼太長還沒註釋,以至於現在看起來有點頭疼。但能AC的代碼都是好代碼吧。

技術分享圖片
 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 using namespace std;
 5 const int MAX = 21;
 6 char num[MAX][10005];
 7 char ans[100000];
 8 bool go = false;
 9 int main()
10 {
11     int n;
12     cin >> n;
13     for(int i = 0; i < n; i++)
14         cin >> num[i];
15 
16     for(int i = 0; i < n - 1; i++)
17         for(int j = 0; j < n - 1 - i; j++)
18         {
19             int j1 = strlen(num[j]);
20             int j2 = strlen(num[j+1]);
21             int x = 0, y = 0;
22             while(x < j1 && y < j2)
23             {
24                 if(num[j][x] < num[j+1][y])
25                 {
26                     char b[10005];
27                     strcpy(b, num[j]);
28                     strcpy(num[j], num[j+1]);
29                     strcpy(num[j+1], b);
30                     go = true;
31                     break;
32                 }
33                 else if(num[j][x] > num[j+1][y]) { go = true; break; }
34                 else if(num[j][x] == num[j+1][y]) x++, y++;
35             }
36             if(!go){
37                 if(j1 < j2){
38                     if(num[j][0] > num[j+1][j1]){
39                         char b[10005];
40                         strcpy(b, num[j]);
41                         strcpy(num[j], num[j+1]);
42                         strcpy(num[j+1], b);
43                     }
44                 } else if(j1 > j2){
45                     if(num[j][j2] < num[j+1][0]){
46                         char b[10005];
47                         strcpy(b, num[j]);
48                         strcpy(num[j], num[j+1]);
49                         strcpy(num[j+1], b);
50                     }
51                 }
52             }
53         }
54 
55     for(int i = 0; i < n; i++)
56         strcat(ans, num[i]);
57 
58     cout << ans << endl;
59 
60     return 0;
61 }
AC代碼

最後小結:

要想熟練運用字符串,除了要熟悉string以外,STL裏的一些容器也要會用。還是得要繼續用功啊!

技術分享圖片

【洛谷】訓練場_字符串處理