文章目录
- 说明
- 例题
-
- 例5-1 UVA 10474 大理石在哪儿 (排序和查找)
- 例5-2 UVA 101 木块问题 (using std::vector)
- 例5-3 UVA 10815 安迪的第一本字典 (using std::set)
- 例5-4 UVA 156 反片语 (using std::map)
- 例5-5 UVA 12096 集合栈计算机 (using std::stack and other containers)
- 例5-6 UVA 540 团体队列 (using std::queue and other containers)
- 例5-7 UVA 136 丑数 (using priority_queue)
- 例5-8 UVA 400 Unix is 命令 (排序和字符串处理)
- 例5-9 UVA 1592 数据库 (uniquely using std::map)
- 例5-10 UVA 207 PGA 巡回赛的奖金 (排序和其他细节处理)(未尝试)
- 例5-11 UVA 814 邮件传输代理的交互 (字符串以及 STL 容器综合运用)(未尝试)
- 例5-12 UVA 221 城市正视图 (离散化)(未尝试)
说明
本文是我对第五章12道例题的练习总结,建议配合紫书——《算法竞赛入门经典(第2版)》阅读本文。
另外为了方便做题,我在VOJ上开了一个contest,欢迎一起在上面做:第五章例题contest
如果想直接看某道题,请点开目录后点开相应的题目!!!
例题
例5-1 UVA 10474 大理石在哪儿 (排序和查找)
思路
这个题比较基础,排序用sort,查找用lower_bound,都是STL的标准函数。注意lower_bound函数的返回值是不小于查找数的第一个位置对应的指针,找不到则返回a+n(也就是函数的第二个参数)。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 10000;
int main(void)
{
int n, q, t = 0;
int a[N], x;
while (scanf("%d%d", &n, &q) != EOF && n) {
for (int i = 0; i < n; i ++)
scanf("%d", &a[i]);
sort(a, a+n);
printf("CASE# %d:\n", ++t);
while (q--) {
scanf("%d", &x);
int m = lower_bound(a, a+n, x) - a;
printf("%d ", x);
if (m == n || a[m] != x) printf("not found\n");
else printf("found at %d\n", m+1);
}
}
return 0;
}
例5-2 UVA 101 木块问题 (using std::vector)
思路
由于此题中木块堆的长度一直在变化,并需要频繁的添加和删除元素操作,用vector是最合适的。
注意学习vector的功能函数用法,如size() resize() push_back()等。
另外,这个题的四种操作中具体操作有一定的重复,合理拆分操作能够使代码模块化更好。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 25;
typedef pair<int, int> P;
int n;
vector<int> pile[N];
P find_pile(int a)
{
for (int i = 0; i < n; i ++) {
for (int j = 0; j < pile[i].size(); j ++) {
if (pile[i][j] == a) return P(i, j);
}
}
return P(n, n);
}
void clear_above(P p)
{
int i = p.first, j = p.second;
for (int k = j+1; k < pile[i].size(); k ++) {
int a = pile[i][k];
pile[a].push_back(a);
}
pile[i].resize(j+1);
}
void pile_over(P p, int b)
{
int i = p.first, j = p.second;
for (int k = j; k < pile[i].size(); k ++) {
int a = pile[i][k];
pile[b].push_back(a);
}
pile[i].resize(j);
}
void print()
{
for (int i = 0; i < n; i ++) {
printf("%d:", i);
for (int j = 0; j < pile[i].size(); j ++) {
printf(" %d", pile[i][j]);
}
printf("\n");
}
}
int main(void)
{
cin >> n;
for (int i = 0; i < n; i ++) pile[i].push_back(i);
string s1, s2;
int a, b;
P p1, p2;
while (cin >> s1 && s1 != "quit") {
cin >> a >> s2 >> b;
p1 = find_pile(a);
p2 = find_pile(b);
if (p1.first == p2.first) continue;
if (s1 == "move") clear_above(p1);
if (s2 == "onto") clear_above(p2);
pile_over(p1, p2.first);
//print();
//printf("============