文章目录
- 说明
- 例题
-
- 例3-1 UVA 272 TeX 中的引号
- 例3-2 UVA 10082 WERTYU
- 例3-3 UVA 401 回文词
- 例3-4 UVA 340 猜数字游戏的提示
- 例3-5 UVA 1583 生成元
- 例3-6 UVA 1584 环状序列
- 习3-1 UVA 1585 得分
- 习3-2 UVA 1586 分子量
- 习3-3 UVA 1225 数数字
- 习3-4 UVA 455 周期串
- 习3-5 UVA 227 谜题
- 习3-6 UVA 232 纵横字谜的答案
- 习3-7 UVA 1368 DNA 序列
- 习3-8 UVA 202 循环小数
- 习3-9 UVA 10340 子序列
- 习3-10 UVA 1587 盒子
- 习3-11 UVA 1588 换低档装置
- 习3-12 UVA 11809 浮点数(未通过)
说明
本文是我对第三章题目的练习总结,建议配合紫书——《算法竞赛入门经典(第2版)》阅读本文。
另外为了方便做题,我在VOJ上开了一个contest,欢迎一起在上面做:第三章contest
如果想直接看某道题,请点开目录后点开相应的题目!!!
例题
例3-1 UVA 272 TeX 中的引号
思路
这个题主要讲带空格的输入输出处理。我总结了一下,主要有三种方案:
1、用getchar()一个一个字符处理
2、用fgets读入(gets已经过时)
3、用getline读入
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main(void)
{
char c;
bool flag = true;
while ((c = getchar()) != EOF) {
if (c == '\"') {
printf("%s", flag ? "``" : "''");
flag = !flag;
} else
printf("%c", c);
}
return 0;
}
例3-2 UVA 10082 WERTYU
思路
常量数组的妙用,可以使程序简洁很多。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char s[] = "`1234567890-=QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./";
int main(void)
{
char c;
while ((c = getchar()) != EOF) {
char *p = strchr(s, c);
if (!p) putchar(c);
else putchar(s[p-s-1]);
}
return 0;
}
例3-3 UVA 401 回文词
思路
常量字符串和字符串数组的妙用,使程序更简洁。
另外,学习了strchr函数,主要功能是在字符串中查找字符,返回字符指针。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const char mirror[] = "A 3 HIL JM O 2TUVWXY51SE Z 8 ";
const char *msg[4] = {" -- is not a palindrome.",
" -- is a regular palindrome.",
" -- is a mirrored string.",
" -- is a mirrored palindrome."};
char trans(char c)
{
if (c <= '9') return mirror[c - '0' + 25];
return mirror[c - 'A'];
}
int main(void)
{
char s[30];
while (cin >> s) {
int p = 1, m = 1;
int n = strlen(s);
for (int i = 0; i <= n/2; i ++) {
if (s[i] != s[n-1-i]) p = 0;
if (trans(s[i]) != s[n-1-i]) m = 0;
}
printf("%s%s\n\n", s, msg[m*2+p]);
}
return 0;
}
例3-4 UVA 340 猜数字游戏的提示
思路
当数值范围较小时,可以用统计数组。我这里判断正确值和错误值的方式与例题稍有不同,思路大同小异。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000;
const int M = 10;
int n, a0[N], c0[M], c2[M];
int a1[N], c1[M];
int main(void)
{
int t = 0;
while (cin >> n && n) {
memset(c0, 0, sizeof(c0));
for (int i = 0; i < n; i ++) {
scanf("%d", &a0[i]);
c0[a0[i]]++;
}
printf("Game %d:\n", ++t);
while (true) {
int flag = false;
int cntA = 0, cntB = 0;
memcpy(c2, c0, sizeof(c0));
memset(c1, 0, sizeof(c1));
for (int i = 0; i < n; i ++) {
scanf("%d", &a1[i]);
if (a1[i]) flag = true;
c1[a1[i]]++;
if (a1[i] == a0[i]) {
cntA ++;
c2[a0[i]] --;
c1[a0[i]] --;
}
}
if (flag == false)
break;
for (int i = 1; i < M; i ++)
if (c2[i]) cntB += min(c1[i], c2[i]);
printf(" (%d,%d)\n", cntA, cntB);
}
}
return 0;
}
例3-5 UVA 1583 生成元
思路
当计算过程复杂而且对结果有多次查询时,就应当考虑将计算结果保存成表,从而大大提高查询效率。
这是本题的主要思想。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100000;
int ma