算法竞赛入门经典(第一版) 第五章 解题报告
一、字符串题目
A - Palindromes
题意:
代码:
B - Where's Waldorf?
题意:
代码:
C - Automatic Poetry
题意:
给出一个字符串,字符串里面被<><>这4个字符分成了4个部分,比如题干的s1<s2>s3<s4>s5;
然后又有一个字符串,使用...,并且保证为...在最后面,我们假设这个字符串除了...以外的部分叫做T
题目意思就是输出T s4 s3 s2 s5 (Ps:空格只是为了好识别)
我使用了C风格的字符串直接读写,检测一下<><>这几个符号就好!
代码:
const int maxn = 110; char s1[maxn], s2[maxn]; char tmp2[maxn], tmp3[maxn], tmp4[maxn], tmp5[maxn]; int main() { #ifdef LOCAL ///freopen("in.txt", "r", stdin); ///freopen("out.txt", "w", stdout); #endif // LOCAL int t; scanf("%d", &t); getchar(); while(t--) { gets(s1); gets(s2); int len = strlen(s1); int flag_1 = 0; int flag_2 = 0; int k2 = 0, k3 = 0, k4 = 0, k5 = 0; for(int i = 0; i < len; ++i) { if (s1[i] == '<' && flag_1 == 0) { int pos = i + 1; while(s1[pos] != '>') { tmp2[k2++] = s1[pos++]; } flag_1 = 1; } else if (s1[i] == '<' && flag_1 == 1) { int pos = i + 1; while(s1[pos] != '>') { tmp4[k4++] = s1[pos++]; } } else if (s1[i] == '>' && flag_2 == 0) { int pos = i + 1; while(s1[pos] != '<') { tmp3[k3++] = s1[pos++]; } flag_2 = 1; } else if (s1[i] == '>' && flag_2 == 1) { int pos = i + 1; while(s1[pos] != '\0') { tmp5[k5++] = s1[pos++]; } } if (s1[i] != '>' && s1[i] != '<') printf("%c", s1[i]); } printf("\n"); tmp2[k2++] = '\0'; tmp3[k3++] = '\0'; tmp4[k4++] = '\0'; tmp5[k5++] = '\0'; int len2 = strlen(s2); for(int i = 0; i < len2; ++i) { if(s2[i] != '.') printf("%c", s2[i]); else { printf("%s%s%s%s\n", tmp4, tmp3, tmp2, tmp5); break; } } } return 0; }
D - Artificial Intelligence?
题意:
题干说了很多,实际就是读取P U I这三个关键。读取其中2个 计算另外一个
区分题干和数据的方法就是'=‘这个字符,我只要检测到这个字符,然后看一看这个字符的前一个是啥,我就能知道最终我要计算的量
然后是读取空格之后的实数部分和单位的前缀部分;
这里我使用了一个函数,double atof (char *) 这个函数能自动识别字符串的实数。具体细节百度!
坑点:如果不使用atof记得检查有没有’-‘ 这个哦 毕竟实数也包括负数!!!
代码:
const int maxn = 100000; char s[maxn]; double check(int pos) { int now = pos; double num; while(!isalpha(s[now])) { now++; } if (s[now] == 'm') return 0.001; else if(s[now] == 'k') return 1000.0; else if (s[now] == 'M') return 1000000.0; else return 1.0; } int main() { #ifdef LOCAL ///freopen("in.txt", "r", stdin); ///freopen("out.txt", "w", stdout); #endif // LOCAL int t; int Ca = 1; scanf("%d\n", &t); getchar(); while(t--) { double P, U, I; bool flag[3]; memset(flag, false, sizeof(flag)); gets(s); int len = strlen(s); for(int i = 0; i < len; ++i) { if (s[i] == '=' && s[i - 1] == 'P') { flag[0] = true; P = atof(&s[i + 1]) * check(i); } else if (s[i] == '=' && s[i - 1] == 'U') { flag[1] = true; U = atof(&s[i + 1]) * check(i); } else if (s[i] == '=' && s[i - 1] == 'I') { flag[2] = true; I = atof(&s[i + 1]) * check(i); } } printf("Problem #%d\n",Ca++); if (!flag[0]) { printf("P=%.2lfW\n\n", U * I); } else if (!flag[2]) { printf("I=%.2lfA\n\n", P / U); } else { printf("U=%.2lfV\n\n", P / I); } } return 0; }
E - Excuses, Excuses!
题意:
代码:
F - Decode the tape
题意:
代码:
G - Andy's First Dictionary
题意:
在一篇文章中,整理出其中的单词,并升序输出。
注意要全部小写,且输出一个单词即可!
比如
a after A
输出应该是
a
after
然后莫名的冲动用了STL的set 外加getchar()一个一个的读入
代码:
int main() { #ifdef LOCAL ///freopen("in.txt", "r", stdin); ///freopen("out.txt", "w", stdout); #endif // LOCAL char c; set<string> s; string tmp; while((c = getchar()) != EOF) { if (!isalpha(c)) { if (tmp.size()) { s.insert(tmp); tmp.erase(); } } else { tmp.push_back(tolower(c)); } } if (tmp.size()) s.insert(tmp); for(set<string>::iterator i = s.begin(); i != s.end(); ++i) cout << *i << endl; return 0; }
H - Immediate Decodability
题意:
给出一个有01组成的二进制集合,题目要求检查这个集合里面每个元素是否是前一个元素的前缀,如果有任何一个元素,作为了其他元素的前缀,就输出
is not immediately decodable否则输出is immediately decodable具体这个有啥用,我也不知道。这道题最快的办法就是用 string 里面的 find函数,看看能不能 返回0, 如果返回0就表示是前缀
代码:
const int maxn = 1000; string code[maxn]; int main() { #ifdef LOCAL ///freopen("in.txt", "r", stdin); ///freopen("out.txt", "w", stdout); #endif // LOCAL string tmp; int k = 0; int Ca = 1; while(cin >> tmp) { if (tmp == "9") { bool flag = false; for(int i = 0; i < k && !flag; ++i) for(int j = i + 1; j < k && !flag; ++j) if(code[i].find(code[j]) == 0 || code[j].find(code[i]) == 0) //第i个和第j个元素,要互相查找一下 flag = true; if (!flag) cout << "Set " << Ca++ << " is immediately decodable" << endl; else cout << "Set " << Ca++ <<" is not immediately decodable" << endl; k = 0; } else code[k++] = tmp; } return 0; }
I - Automatic Editing
题意:
说了很多细节,其实就和我们的文本编辑器的查找再替换是一个样。所以输入的相当于是查找的值和替换的值。
有一个需要注意的地方,那就是,查找与替换必须把一组关键词用到不能用了为止,然后才能试用下一组!
这里使用了C++的来写这道题
使用string的replace函数,这是一个重载函数,我使用的是这个版本——》 replace(原字符串位置,替换字符串长度,替换字符串);
这道题目暂时没有发现坑点!
代码:
int main() { #ifdef LOCAL ///freopen("in.txt", "r", stdin); ///freopen("out.txt", "w", stdout); #endif // LOCAL int t; string tmp, key; while(cin >> t && t) { vector<string> pwd1; vector<string> pwd2; cin.ignore(); //偷学的 据说可以和getchar()等效 for(int i = 1; i <= 2 * t; ++i) { getline(cin, tmp); if (i & 1) pwd1.push_back(tmp); else pwd2.push_back(tmp); } getline(cin, key); for(int k = 0; k < t; ++k) { int pos; while((pos = key.find(pwd1[k])) != string::npos) //根据规则 必须查找替换到,当前关键词无法使用为止 { key.replace(pos, pwd1[k].size(), pwd2[k]); } } cout << key << endl; } return 0; }