第一题:340 - Master-Mind Hints
题目大意:给定密码长度,然后是密码占一行,然后每一行是一个猜测,需要找出这行猜测有几个位置相同且密码相同的个数,几个位置不同但密码匹配的个数;前者个数为A,后者个数为B,匹配优先前者比如说密码为 1 2 3 4,猜测为 2 2 1 3,则A = 1, B = 2。读入直到猜测都为0。
解题思路: 先找位置相同的匹配并标记为已匹配,然后找不同位置的匹配,找到一个标记一个。
解题代码:
1 //#define LOCAL //Please annotate this line when you submit 2 #ifdef WINDOWS 3 #define LL __int64 4 #define LLD "%I64d" 5 #else 6 #define LL long long 7 #define LLD "%lld" 8 #endif 9 /********************************************************/ 10 #include <iostream> 11 #include <stdio.h> 12 #include <math.h> 13 #include <algorithm> 14 #include <string.h> 15 #include <string> 16 #include <map> 17 using namespace std; 18 const int max_n = 1002; 19 20 int s[max_n]; 21 bool had_s[max_n], had_g[max_n]; 22 int g[max_n]; 23 24 int main() 25 { 26 #ifdef LOCAL 27 freopen("data.in", "r", stdin); 28 freopen("data.out", "w", stdout); 29 #endif 30 int n; 31 int total; 32 int a, b; 33 int T = 1; 34 while (~scanf ("%d", &n) && n) 35 { 36 printf("Game %d: ", T ++); 37 for (int i = 0; i < n; i ++) 38 scanf("%d", &s[i]); 39 while (1) 40 { 41 total = 0; 42 memset(had_s, false, sizeof(had_s)); 43 memset(had_g, false, sizeof(had_g)); 44 a = b = 0; 45 for (int i = 0; i < n; i ++) 46 { 47 scanf ("%d", &g[i]); 48 total += g[i]; 49 } 50 if (!total) 51 break; 52 for (int i = 0; i < n; i ++) 53 { 54 if (g[i] == s[i]) 55 { 56 a ++; 57 had_s[i] = true; 58 had_g[i] = true; 59 } 60 } 61 for (int i = 0; i < n; i ++) 62 { 63 for (int j = 0; j < n; j ++) 64 { 65 if (g[i] == s[j] && !had_s[j] && !had_g[i]) 66 { 67 b ++; 68 had_s[j] = true; 69 had_g[i] = true; 70 break; 71 } 72 } 73 } 74 printf(" (%d,%d) ", a, b); 75 } 76 77 } 78 return 0; 79 }
第二题:10420 - List of Conquests
题目大意:找出来自同一城市的美女,首先输入人数n,然后n行,每行第一个单词即为美女所在城市,统计来自同一城市的人数,并按字典序输出城市名与来自此城市的人数。
解题思路:直接匹配即可。
解题代码:
1 // File Name :10420 - List of Conquests 2 // Author :Freetion 3 4 5 #include <stdio.h> 6 #include <iostream> 7 #include <map> 8 #include <string> 9 #include <string.h> 10 #include <algorithm> 11 using namespace std; 12 13 const int max_n = 2002; 14 int main() 15 { 16 char name[80]; 17 string str[max_n]; 18 int n; 19 while (scanf("%d", &n) == 1) 20 { 21 getchar(); 22 for (int i = 0; i < n; i ++) 23 { 24 gets(name); 25 str[i].clear(); 26 int len = strlen(name); 27 for (int j = 0; name[j] != ' '; j ++) 28 str[i] += name[j]; 29 30 } 31 sort(str, str+n); 32 int sum = 0; 33 string tm = str[0]; 34 for (int i = 0; i < n; i ++) 35 { 36 if (str[i] == tm) 37 sum ++; 38 else 39 { 40 cout << tm; 41 printf(" %d ", sum); 42 tm.clear(); 43 tm = str[i]; 44 sum = 1; 45 } 46 } 47 cout << tm; 48 printf(" %d ", sum); 49 50 } 51 }
第三题:10474 - Where is the Marble?
题目大意:给你大理石的数量,以及询问次数,然后输入石块大小,石块大小是无序输入的,但之前是从小到大都已经编号,然后是询问,每次询问一个数即石块的大小,这么大的石块的编号是多少,并输出。水题,排序,查找。
解题代码:
1 // File Name :10474.cpp 2 // Author :Freetion 3 4 5 //#define LOCAL //Please annotate this line when you submit 6 /********************************************************/ 7 #include <iostream> 8 #include <stdio.h> 9 #include <math.h> 10 #include <algorithm> 11 #include <string.h> 12 #include <string> 13 #include <map> 14 #define CLE(name) memset(name, 0, sizeof(name)) 15 using namespace std; 16 17 const int max_n = 100003; 18 int mar[max_n]; 19 20 int main() 21 { 22 #ifdef LOCAL 23 freopen("data.in", "r", stdin); 24 freopen("data.out", "w", stdout); 25 #endif 26 int n, q, x; 27 int T = 1; 28 while (~scanf("%d%d", &n, &q) && (n + q)) 29 { 30 printf("CASE# %d: ", T ++); 31 for (int i = 0; i < n; i ++) 32 scanf("%d", &mar[i]); 33 sort(mar, mar+n); 34 for (int i = 0; i < q; i ++) 35 { 36 scanf ("%d", &x); 37 int j; 38 for (j = 0; j < n; j ++) 39 { 40 if (x == mar[j]) 41 { 42 printf("%d found at %d ", x, j+1); 43 break; 44 } 45 } 46 if (j == n) 47 printf("%d not found ", x); 48 } 49 } 50 return 0; 51 }
第四题:152 - Tree's a Crowd
题目大意;相当于给你多个三维空间点的坐标,选取一个点找到到该点的最小距离,并将拥有这个最小距离的点数+1,直到取完所有的点,然后输出,距离为0,1,2,3,4,5,6,7,8,9的点数。
解题思路;水题,直接计算即可;
解题代码:
1 // File Name :152 - Tree's a Crowd.cpp 2 // Author :Freetion 3 4 5 //#define LOCAL //Please annotate this line when you submit 6 /********************************************************/ 7 #include <iostream> 8 9 #include <stdio.h> 10 #include <math.h> 11 #include <algorithm> 12 #include <string.h> 13 #include <string> 14 #include <map> 15 #define CLE(name) memset(name, 0, sizeof(name)) 16 using namespace std; 17 18 const int max_n = 5003; 19 struct Point 20 { 21 int x, y, z; 22 int operator - (const Point p) const 23 { 24 int ans; 25 ans = (int)sqrt((x - p.x)*(x - p.x) + (y - p.y)*(y - p.y) + (z - p.z)*(z - p.z)); 26 return ans; 27 } 28 }point[max_n]; 29 30 int main() 31 { 32 int x, y, z; 33 int num = 0; 34 int dis[10]; 35 CLE(dis); 36 while (~scanf("%d%d%d", &x, &y, &z) && (x+y+z)) 37 { 38 point[num ++] = (Point){x, y, z}; 39 } 40 for (int i = 0; i < num; i ++) 41 { 42 int min = 0x3fffffff; 43 for (int j = 0; j < num; j ++) 44 { 45 if (i == j) 46 continue; 47 int tm = point[i] - point[j]; 48 if (min > tm) 49 min = tm; 50 } 51 dis[min] ++; 52 } 53 for (int i = 0; i < 10; i ++) 54 printf("%4d", dis[i]); 55 puts(""); 56 }
第五题:299 - Train Swapping
题目大意:一辆列车,相邻的两节车厢可以交换,要你找出最小的交换次数,使得列车按升序排列;
解题思路:写个冒泡排序即可;
解题代码:
1 // File Name :299.cpp 2 // Author :Freetion 3 4 5 #define LOCAL //Please annotate this line when you submit 6 /********************************************************/ 7 #include <iostream> 8 #include <stdio.h> 9 #include <math.h> 10 #include <algorithm> 11 #include <string.h> 12 #include <string> 13 #include <map> 14 #define CLE(name) memset(name, 0, sizeof(name)) 15 using namespace std; 16 17 int main() 18 { 19 #ifdef LOCAL 20 freopen("data.in", "r", stdin); 21 freopen("data.out", "w", stdout); 22 #endif 23 int T, n; 24 int tra[100]; 25 scanf("%d", &T); 26 while (T--) 27 { 28 scanf ("%d", &n); 29 for (int i = 0; i < n; i ++) 30 scanf ("%d", &tra[i]); 31 int ans = 0; 32 for (int i = 0; i < n-1; i ++) 33 { 34 for (int j = i+1; j < n; j ++) 35 { 36 if (tra[i] > tra[j]) 37 { 38 tra[i] = tra[i]^tra[j]; 39 tra[j] = tra[j]^tra[i]; 40 tra[i] = tra[i]^tra[j]; 41 ans ++; 42 } 43 } 44 } 45 printf("Optimal train swapping takes %d swaps. ", ans); 46 } 47 }
第六题:120 - Stacks of Flapjacks
题目大意:给你一堆煎饼,每个煎饼半径各不相同,位置为n的地方相当于锅的低端,然后然你的刀从中间某一位插进去进行翻转,当然只能向上翻转,然后找出最少的次数使得煎饼大小从小到大排列,并依次输出翻转的位置,直到不用进行翻转,输出位置0,由于是逆序,所以,位置为n的地方相当于位置1,反之亦然;
解题思路:每次找到半径最大的煎饼位置(如果它已经在它本应呆的位置则跳过)往上翻转到顶端,如果已经在顶端,则不翻转,然后找到它本应呆的位置在翻转,然后循环直到所有的都排好序,由于输出还要有原顺序,所以需要两个数组保存数据,一个用来做,另一个输出。
解题代码:
1 // File Name :120 - Stacks of Flapjacks.cpp 2 // Author :Freetion 3 4 5 #define LOCAL //Please annotate this line when you submit 6 /********************************************************/ 7 #include <iostream> 8 #include <stdio.h> 9 #include <math.h> 10 #include <algorithm> 11 #include <string.h> 12 #include <string> 13 #include <map> 14 #define CLE(name) memset(name, 0, sizeof(name)) 15 using namespace std; 16 17 const int max_n = 33; 18 int sta[max_n], fu[max_n]; 19 20 int main() 21 { 22 char str[2*max_n]; 23 int pos[max_n], temp[max_n]; 24 while (gets(str)) 25 { 26 int len = strlen(str); 27 int cun = 1; 28 CLE(sta); 29 for (int i = 0; i < len; i ++) 30 { 31 while(str[i] != ' ' && i < len) 32 { 33 sta[cun] = sta[cun]*10 + str[i] - '0'; 34 i ++; 35 } 36 fu[cun] = sta[cun]; 37 cun ++; 38 39 } 40 for(int i = 1; i < cun; i ++) 41 { 42 // cout << sta[i] << " "; 43 temp[i] = sta[i]; 44 } 45 sort(temp+1, temp+cun); 46 int re = 0; 47 int last = cun - 1; 48 for (int i = cun - 1; i >= 1; i --) 49 { 50 int M = temp[i]; 51 for (int j = i; j >=0; j--) 52 { 53 if (M == sta[j]) 54 { 55 if (j == i) 56 break; 57 if (j != 1) 58 { 59 pos[re++] = j; 60 for (int k = 1; k <= j/2; k ++) 61 { 62 sta[k] = sta[k] ^ sta[j-k+1]; 63 sta[j-k+1] = sta[j-k+1] ^ sta[k]; 64 sta[k] = sta[k] ^ sta[j-k+1]; 65 66 } 67 } 68 pos[re++] = i; 69 for (int k = 1; k <= i/2; k ++) 70 { 71 sta[k] = sta[k] ^ sta[i-k+1]; 72 sta[i-k+1] = sta[i-k+1] ^ sta[k]; 73 sta[k] = sta[k] ^ sta[i-k+1]; 74 75 } 76 break; 77 } 78 79 } 80 } 81 for (int i = 1; i < cun; i ++) 82 printf("%d%c", fu[i], i != cun-1 ? ' ' : ' '); 83 for (int i = 0; i < re; i ++) 84 printf("%d ", cun - pos[i]); 85 printf("0 "); 86 } 87 return 0; 88 }
第七题:156 - Ananagrams
题目大意:给你一段文字,以#键结束,找出中间每个单词以任何顺序排列都没有出现第二次的单词;
解题思路:刚开始想到排列组合,但是发现很不现实,百度一下才知将每个单词转换成小写字母,然后以字典序排好,依次比较看有没有重复的,有即标记,最后输出没有标记的单词,但是要是原单词,所以这题也许两个数组,存储单词。由于要按字典序输出单词,所以我们需要先排序后判断。
解题代码:
1 //#define LOCAL //Please annotate this line when you submit 2 #ifdef WINDOWS 3 #define LL __int64 4 #define LLD "%I64d" 5 #else 6 #define LL long long 7 #define LLD "%lld" 8 #endif 9 /********************************************************/ 10 #include <iostream> 11 #include <stdio.h> 12 #include <math.h> 13 #include <algorithm> 14 #include <string.h> 15 #include <string> 16 #include <map> 17 #define CLE(name, a) memset(name, a, sizeof(name)) 18 using namespace std; 19 20 const int max_w = 1004; 21 const int max_l = 100; 22 string word[max_w], deel[max_w]; 23 char temp[max_l]; 24 bool have[max_w]; 25 int cun; 26 27 void solve() 28 { 29 for (int k = 0; k < cun-1; k ++) 30 { 31 int len = word[k].length(); 32 for (int i = 0; i < len; i ++) 33 { 34 if (word[k][i] <= 'Z') 35 temp[i] = word[k][i] + 32; 36 else temp[i] = word[k][i]; 37 38 } 39 sort(temp, temp+len); 40 deel[k] = ""; 41 for (int i = 0; i < len; i ++) 42 deel[k] += temp[i]; 43 for (int i = 0; i < k; i ++) 44 { 45 int tm = deel[i].length(); 46 if (tm == len) 47 { 48 int j; 49 for (j = 0; j < len; j ++) 50 { 51 if (deel[i][j] != deel[k][j]) 52 break; 53 } 54 if (j == len) 55 { 56 have[i] = true; 57 have[k] = true; 58 } 59 } 60 } 61 } 62 } 63 64 int main() 65 { 66 #ifdef LOCAL 67 freopen("data.in", "r", stdin); 68 freopen("data.out", "w", stdout); 69 #endif 70 cun = 0; 71 CLE(have, false); 72 while (cin >> word[cun ++]) 73 { 74 if (word[cun-1][0] == '#') 75 break; 76 } 77 sort(word, word+cun-1); 78 solve(); 79 for (int i = 0; i < cun-1; i ++) 80 { 81 if (!have[i] == 1) 82 cout << word[i] << endl; 83 } 84 return 0; 85 }
第八题:400 - Unix ls
题目大意:输入整数n,然后n行,每行一个文件名,输出:将文件按字典序排序,然后按列优先的顺序,输出每行所占字符不超过60个,每列之间的间距以最长文件名加上两个字符的长度为准。
解题思路:此题不难,但输出需要控制好,此题很容易RE,原因可能是数组开得小,以0为除数等,此题要求所占字符不超过60,但是应该有数据的长度刚好是60,再加上 2,就可能造成数组开61的越界,也就RE,而我就是以0为除数造成RE。
解题代码:
1 #define LOCAL //Please annotate this line when you submit 2 #ifdef WINDOWS 3 #define LL __int64 4 #define LLD "%I64d" 5 #else 6 #define LL long long 7 #define LLD "%lld" 8 #endif 9 /********************************************************/ 10 #include <iostream> 11 #include <stdio.h> 12 #include <math.h> 13 #include <algorithm> 14 #include <string.h> 15 #include <string> 16 #include <map> 17 using namespace std; 18 const int max_n = 110; 19 string file[max_n]; 20 21 int main() 22 { 23 #ifdef LOCAL 24 freopen("data.in", "r", stdin); 25 freopen("data.out", "w", stdout); 26 #endif 27 int n; 28 int max_l; 29 int x, y; 30 while (~scanf("%d", &n)) 31 { 32 max_l = 0; 33 for (int i = 0; i < n; i ++) 34 { 35 cin >> file[i]; 36 if (max_l < file[i].length()) 37 max_l = file[i].length(); 38 } 39 sort(file, file+n); 40 max_l += 2; 41 printf("------------------------------------------------------------ "); 42 x = max_l > 60 ? 1 : 60/max_l;//处理加上2之后的最大长度超过60的情况。如果不处理就会使得x为0,再用x作为除数就会出现RE 43 y = n/x; 44 if (n%x) 45 y ++; 46 for (int i = 0; i < y; i ++ ) 47 { 48 for (int j = 0; j < x; j ++) 49 { 50 if (i+j*y < n) 51 { 52 int len = file[i+j*y].length(); 53 cout << file[i+j*y]; 54 for (int k = len+1; k <= max_l; k ++) 55 printf(" "); 56 } 57 } 58 printf(" "); 59 } 60 } 61 return 0; 62 }
第九题:123 - Searching Quickly
题目大意:首先输入多个单词,以::结束;然后给几句话,直到EOF,找出::以前没有出现过的单词作为关键字,然后将关键字按字典序排序,按关键词的顺序,输出句子中出现过了关键词的句子,并且关键字要大写,一个句子中出现过多次同一关键字,也要依次输出多次,每次将对应的关键字大写。
解题思路:这题也水,只是输出的处理而已。
解题代码:
1 #define LOCAL //Please annotate this line when you submit 2 #ifdef WINDOWS 3 #define LL __int64 4 #define LLD "%I64d" 5 #else 6 #define LL long long 7 #define LLD "%lld" 8 #endif 9 /********************************************************/ 10 #include <iostream> 11 #include <stdio.h> 12 #include <math.h> 13 #include <algorithm> 14 #include <string.h> 15 #include <string> 16 #include <map> 17 using namespace std; 18 const int max_n = 10005; 19 string key_w[max_n], tm; 20 char input[205][max_n]; 21 char ign_w[53][14]; 22 23 int main() 24 { 25 #ifdef LOCAL 26 freopen("data.in", "r", stdin); 27 freopen("data.out", "w", stdout); 28 #endif 29 bool ign = true; 30 int ign_num = 0; 31 int key_num = 0; 32 int input_num = 0; 33 char *need; 34 while (scanf ("%s", ign_w[ign_num]) != EOF) 35 { 36 for (int i = 0; i < strlen(ign_w[ign_num]); i ++) 37 if (ign_w[ign_num][i] <= 'Z' && ign_w[ign_num][i] >= 'A') 38 ign_w[ign_num][i] += 32; 39 ign_num ++; 40 if (ign_w[ign_num-1][0] == ':') 41 { 42 ign_num --; 43 break; 44 } 45 } 46 while(gets(input[input_num++])) 47 { 48 int len = strlen(input[input_num-1]); 49 for (int i = 0; i < len; i ++) 50 { 51 if (input[input_num-1][i] <= 'Z' && input[input_num-1][i] >= 'A') 52 input[input_num-1][i] += 32; 53 if (input[input_num-1][i] != ' ') 54 tm += input[input_num-1][i]; 55 if (input[input_num-1][i] == ' ' || i == len-1) 56 { 57 int j; 58 for (j = 0; j < key_num; j ++) 59 { 60 int len_t = tm.length(); 61 int len_k = key_w[j].length(); 62 if (len_t == len_k) 63 { 64 int pos; 65 for (pos = 0; pos < len_t; pos++) 66 { 67 if (tm[pos] != key_w[j][pos]) 68 break; 69 } 70 if (pos == len_t) 71 break; 72 73 } 74 } 75 if (j == key_num) 76 { 77 int k; 78 for (k = 0; k < ign_num; k ++) 79 { 80 int len_i = strlen(ign_w[k]); 81 int len_t = tm.length(); 82 if (len_i == len_t) 83 { 84 int pos; 85 for (pos = 0; pos < len_t; pos ++) 86 if (tm[pos] != ign_w[k][pos]) 87 break; 88 if (pos == len_t) 89 break; 90 } 91 } 92 if (k == ign_num) 93 key_w[key_num++] = tm; 94 } 95 tm.clear(); 96 } 97 } 98 } 99 sort(key_w, key_w+key_num); 100 for (int i = 0; i < key_num; i ++) 101 { 102 int len_k = key_w[i].length(); 103 for (int j = 0; j < input_num; j ++) 104 { 105 int len_in = strlen(input[j]); 106 for (int k = 0; k < len_in; k ++) 107 { 108 if (k == 0 || input[j][k-1] == ' ') 109 { 110 int pos = 0; 111 while (pos < len_k) 112 { 113 if (input[j][k] != key_w[i][pos]) 114 break; 115 pos ++; 116 k ++; 117 } 118 if (pos == len_k && (input[j][k] == ' ' || input[j][k] == '