UVa 11882:Biggest Number(DFS+剪枝)
2015-09-13 21:01
323 查看
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=842&page=show_problem&problem=3004
题意:在一个R行C列(2≤R,C≤15,R∗C≤30)(2 \le R, C \le 15, R*C \le 30 )的矩阵里有障碍物和数字格(包含1~9的数字)。你可以从任意一个数字格出发,每次沿着上下左右之一的方向走一格,但不能走到障碍格中,也不能重复经过一个数字格,然后把沿途经过的所有数字连起来,如图所示。如图可以得到9784,4832145等整数。问:能得到的最大整数是多少?(本段摘自《算法竞赛入门经典(第2版)》)
分析:
枚举起点进行DFS即可。有一个最优性剪枝,即当当前位置的时候,剩下可以走的最大长度加上已走长度如果仍然小于当前最优的答案时,直接return,如果相等但是字典序比当前最优答案小的话也直接return。
代码:
题意:在一个R行C列(2≤R,C≤15,R∗C≤30)(2 \le R, C \le 15, R*C \le 30 )的矩阵里有障碍物和数字格(包含1~9的数字)。你可以从任意一个数字格出发,每次沿着上下左右之一的方向走一格,但不能走到障碍格中,也不能重复经过一个数字格,然后把沿途经过的所有数字连起来,如图所示。如图可以得到9784,4832145等整数。问:能得到的最大整数是多少?(本段摘自《算法竞赛入门经典(第2版)》)
分析:
枚举起点进行DFS即可。有一个最优性剪枝,即当当前位置的时候,剩下可以走的最大长度加上已走长度如果仍然小于当前最优的答案时,直接return,如果相等但是字典序比当前最优答案小的话也直接return。
代码:
#include <iostream> #include <algorithm> #include <fstream> #include <cstring> #include <vector> #include <queue> #include <cmath> #include <cctype> #include <stack> #include <set> using namespace std; const int maxn = 20 + 5; const int dx[] = {0, 0, -1, 1}, dy[] = {1, -1, 0, 0}; struct Node { int x, y; }; int r, c; char a[maxn][maxn]; int v[maxn][maxn], vv[maxn][maxn]; string ans, tmp; Node q[maxn * maxn]; void update(const string& s) { int l1 = ans.size(), l2 = s.size(); if ((l1 < l2) || (l1 == l2 && s > ans)) ans = s; } int h(int x, int y) { int head = 0, tail = 0, cnt = 0; q[tail].x = x; q[tail++].y = y; memcpy(vv, v, sizeof(v)); while (head != tail) { for (int i = 0; i < 4; ++i) { int xx = q[head].x + dx[i], yy = q[head].y + dy[i]; if (xx >= 0 && xx < r && yy >= 0 && yy < c && a[xx][yy] != '#' && !vv[xx][yy]) { q[tail].x = xx; q[tail++].y = yy; ++cnt; vv[xx][yy] = 1; } } ++head; } return cnt; } void DFS(int x, int y, string s, int deep) { int l = h(x, y); if (l + deep < ans.size()) return; if (l + deep == ans.size() && (s + "z") < ans) return; update(s); for (int i = 0; i < 4; ++i) { int xx = x + dx[i], yy = y + dy[i]; if (xx >= 0 && xx < r && yy >= 0 && yy < c && a[xx][yy] != '#' && !v[xx][yy]) { v[xx][yy] = 1; DFS(xx, yy, s + a[xx][yy], deep + 1); v[xx][yy] = 0; } } } int main() { while (~scanf("%d%d", &r, &c), r || c) { ans = ""; for (int i = 0; i < r; ++i) scanf("%s", a[i]); for (int i = 0; i < r; ++i) for (int j = 0; j < c; ++j) if (a[i][j] != '#') { memset(v, 0, sizeof(v)); v[i][j] = 1; tmp = ""; tmp += a[i][j]; DFS(i, j, tmp, 1); } cout << ans << '\n'; } return 0; }
相关文章推荐
- c++11——右值引用
- C++达到String分类
- POJ 2305大数求余
- ssh scp 复制文件和文件夹
- 能承受为生,侮辱技术好吗?
- HTML表单介绍
- C语言漫谈(二)
- Arraylist与Hashset的判断元素相同的依据
- Java中HashMap遍历的两种方式
- 实验室聚会感悟
- HTML&CSS Learning Notes 2
- hdu 5438 Ponds dfs
- hdu 5443 The Water Problem
- 浅析extern “C”的作用
- 杭州电子科技大学acm--2017
- 移动端的click
- 拉普拉斯矩阵/映射/聚类
- JS基本语法
- IT男的工作现状
- 欢迎使用CSDN-markdown编辑器