UVa11882 Biggest Number (DFS+剪枝)

链接:http://vjudge.net/problem/23314

分析:两种剪枝方案。

  1.找出在当前位置下还能够到达的点的个数(尽管实际能到达的点的个数比它小,但乐观估计就可以了),若当前数字加上个数仍小于目前最优解的长度,则剪枝。

  2.若将还能够到达的数字按从小到大连接到当前数字后面,若仍比目前最优解小,则剪枝。(找出所有还能够到达的点用BFS实现(乐观估计))。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <cstring>
 6 #include <queue>
 7 using namespace std;
 8
 9 const int maxn = 15 + 5;
10
11 int n, m, v[30];
12 string ans;
13 char maze[maxn][maxn];
14 bool vis[maxn][maxn], mark[maxn][maxn];
15
16 bool smaller(string num) {
17     if (num.size() > ans.size()) return true;
18     else if (num.size() == ans.size() && num > ans) return true;
19     else return false;
20 }
21
22 const int dx[4] = {1, -1, 0, 0};
23 const int dy[4] = {0, 0, 1, -1};
24 int bfs(int x, int y) {
25     queue<pair<int, int> > q;
26     memset(mark, 0, sizeof(mark));
27     q.push(make_pair(x, y));
28     mark[x][y] = true;
29     int cnt = 0;
30     while (!q.empty()) {
31         pair<int, int> u = q.front(); q.pop();
32         for (int dir = 0; dir < 4; dir++) {
33             int nx = u.first + dx[dir], ny = u.second + dy[dir];
34             if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
35             if (maze[nx][ny] == ‘#‘ || vis[nx][ny] || mark[nx][ny]) continue;
36             mark[nx][ny] = true;
37             v[cnt++] = maze[nx][ny] - ‘0‘;
38             q.push(make_pair(nx, ny));
39         }
40     }
41     return cnt;
42 }
43
44 void dfs(int x, int y, string num) {
45     if (smaller(num)) ans = num;
46     else {
47         int cnt = bfs(x, y);
48         if (num.size() + cnt < ans.size()) return;
49         if (num.size() + cnt == ans.size()) {
50             sort(v, v + cnt);
51             string num2 = num;
52             for (int i = cnt - 1; i >= 0; i--)
53                 num2 += char(v[i] + ‘0‘);
54             if (!smaller(num2)) return;
55         }
56     }
57     for (int dir = 0; dir < 4; dir++) {
58         int nx = x + dx[dir], ny = y + dy[dir];
59         if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
60         if (maze[nx][ny] == ‘#‘) continue;
61         if (vis[nx][ny]) continue; else vis[nx][ny] = true;
62         dfs(nx, ny, num + maze[nx][ny]);
63         vis[nx][ny] = false;
64     }
65 }
66
67 void solve() {
68     for (int i = 1; i <= n; i++)
69         for (int j = 1; j <= m; j++) {
70             if (maze[i][j] == ‘#‘) continue;
71             memset(vis, false, sizeof(vis));
72             vis[i][j] = true;
73             string num = "";
74             num += maze[i][j];
75             dfs(i, j, num);
76         }
77     cout << ans << endl;
78 }
79
80 int main() {
81     while (cin >> n >> m && n) {
82         for (int i = 1; i <= n; i++) scanf("%s", maze[i] + 1);
83         ans.clear(); solve();
84     }
85     return 0;
86 }
时间: 2024-08-14 08:26:45

UVa11882 Biggest Number (DFS+剪枝)的相关文章

UVA11882 Biggest Number 强剪枝

题目链接: UVA11882 解题思路: 常规思路是 枚举每个点,暴力dfs,然后选择最大的那个  但题目只给了1000MS 这就需要剪枝了 剪枝1: 假设当前答案长度为ans,那么当我们走到一个点(x, y)的时候,bfs一下判断能接触的格子数.假设现在能从(x, y)走到的点,我们都能到达,这是最好的情况.设从(x, y)能走到的点数为maxlen,那么如果从出发点走到(x, y)经过的格子,加上maxlen,都没有ans的长度大,那么不管从(x, y)怎么搜,我们都不能取代我们现在的ans

湖南省第六届省赛题 Biggest Number (dfs+bfs,好题)

Biggest Number 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 You have a maze with obstacles and non-zero digits in it: You can start from any square, walk in the maze, and finally stop at some square. Each step, you may only walk into one of the four neighb

UVA-11882 Biggest Number (DFS+剪枝)

题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的点的个数,若当前数字的长度加上个数仍小于目前最优答案的长度,则剪去:若长度相等,则将所有还能到达的数字按从大到小排序后连到当前数字上,如果还比目前最优解小,则减去.找出所有还能到达的点的过程用BFS实现. 代码如下: # include<iostream> # include<cstdio&

UVA - 11882 Biggest Number(dfs+bfs+强剪枝)

题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的点的个数,若当前数字的长度加上个数仍小于目前最优答案的长度,则剪去:若长度相等,则将所有还能到达的数字按从大到小排序后连到当前数字上,如果还比目前最优解小,则减去.找出所有还能到达的点的过程用BFS实现. 1 #pragma comment(linker, "/STACK:1024000000,10

UVa11882,Biggest Number

搜索+剪枝 如此水的一个题,居然搞了一上午 出错在bfs与dfs时共用了一个vis数组,导致bfs完后返回dfs应该能访问到的点访问不到 自己想怎么剪枝,想了几个剪枝方法,又证明,又推翻,再想,再证明,再推翻用了好长时间T T自己还是水的不行啊 两个剪枝: 1.若,当前求出来的解now的长度+当前状态下从now节点(因为可能有多个连通块,用vis[]判断未访问到的节点是不行的)开始能访问到的节点的个数(bfs遍历即可)<当然ans的长度,那么剪枝.这样大概能减掉一半的枝叶.但是可能还会超时 2.

POJ 1564 Sum It Up (DFS+剪枝)

 Sum It Up Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5820   Accepted: 2970 Description Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t = 4

EOJ1981 || POJ1011 经典dfs+剪枝+奇怪的数据

题目:EOJ1981 || POJ1011   经典dfs+剪枝+奇怪的数据 Description George took sticks of the same length and cut them randomly until all partsbecame at most 50 units long. Now he wants to return sticks to the originalstate, but he forgot how many sticks he had origi

HDOJ 5113 Black And White DFS+剪枝

DFS+剪枝... 在每次DFS前,当前棋盘的格子数量的一半小于一种颜色的数量时就剪掉 Black And White Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 194    Accepted Submission(s): 50 Special Judge Problem Description In mathematics,

poj 1724:ROADS(DFS + 剪枝)

ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Description N cities named with numbers 1 ... N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll