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 neighbouring squares (up, down, left, right) and you cannot walk into obstacles or walk into a square more than once. When you finish, you can get a number by writing down the digits you encounter in the same order as you meet them. For example, you can get numbers 9784, 4832145, etc. The biggest number you can get is 791452384, shown in the picture above.

Your task is to find the biggest number you can get.

Input

There will be at most 25 test cases. Each test begins with two integers R and C (2R,C15, R*C30), the number of rows and columns of the maze. The next R rows represent the maze. Each line contains exactly Ccharacters (without leading or trailing spaces), each of them will be either `#' or one of the nine non-zero digits. There will be at least one non-obstacle squares (i.e. squares with a non-zero digit in it) in the maze. The input is terminated by a test case with R = C = 0, you should not process it.

Output

For each test case, print the biggest number you can find, on a single line.

题目大意:有一个R*C的矩阵,矩阵里面有1~9的数字(太好了不用处理前导0),或者是#(代表不能通过),先要从矩阵任意一点出发(之前英语抓鸡看成了边界,英语差的孩纸伤不起啊>_<),只能往上下左右四个方向移动,每个格子不能重复走,到达矩阵内任意一点。把这条路径的数字连起来变成一个很大的数字,求这个数字最大是什么。
思路:DP?记忆化搜索?30个点噢,时间吃得消内存都吃不消啦。所以呢?搜索。还是超时啊?剪枝啊。
剪枝1:假设当前答案为ans,那么当我们走到一个点(x, y)的时候,作一个小小的搜索预判。假设现在能从(x, y)走到的点,我们都能到达,这是最好的情况。设从(x, y)能走到的点数为maxlen,那么如果从出发点走到(x, y)经过的格子,加上maxlen,都没有ans的长度大,那么不管从(x, y)怎么搜,我们都不能取代我们现在的ans(长才是王道懂不懂),那么直接回溯,不要这个点了。这个剪枝效力还是不错的,但是还是TLE,我试过了QAQ。最近有点脑残,明明可以做一个数据测试一下非要交上去试一下……
剪枝2:同剪枝1,假设当前答案为ans,那么当我们走到一个点(x, y)的时候,搜到maxlen(同剪枝1),如果从出发点走到(x, y)经过的格子,加上maxlen,大于ans的长度,我们就只能继续搜了……如果等于呢?那么就再作一个最好预期的答案。把从(x, y)能走到的所有格子,从大到小排好序(我的代码是从小到大排序然后从后面开始取的……),都接在当前走到(x, y)的后面,这是从(x, y)可能搜到的最好的答案,如果这个都比ans要小,那么我们也就没有必要往下搜了,果断回溯。
PS:弄个结构体存答案很好写妥妥的。

代码(866MS):

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL; const int MAXN = ; struct Node {
int a[MAXN], len;
void clear() {
len = ;
}
void print() {
//cout<<len<<endl;
for(int i = ; i < len; ++i) printf("%d", a[i]);
printf("\n");
}
bool operator < (const Node &rhs) const {
if(len != rhs.len) return len < rhs.len;
for(int i = ; i < len; ++i)
if(a[i] != rhs.a[i]) return a[i] < rhs.a[i];
return false;
}
}; int fx[] = {, , -, };
int fy[] = {, , , -}; Node ans, now, tmp;
char mat[MAXN][MAXN];
bool vis[MAXN][MAXN];
bool vis2[MAXN][MAXN];
int n, m;
int can[MAXN]; int maxlen(int x, int y) {
queue<int> que; que.push(x * MAXN + y);
int ret = ;
can[] = mat[x][y] - '';
memset(vis2, , sizeof(vis2));
vis2[x][y] = ;
while(!que.empty()) {
int tmp = que.front(); que.pop();
int nx = tmp / MAXN, ny = tmp % MAXN;
for(int i = ; i < ; ++i) {
int px = nx + fx[i], py = ny + fy[i];
if(!isdigit(mat[px][py]) || vis[px][py] || vis2[px][py]) continue;
vis2[px][py] = true;
can[ret++] = mat[px][py] - '';
que.push(px * MAXN + py);
}
}
return ret;
} void dfs(int x, int y) {
now.a[now.len++] = mat[x][y] - '';
vis[x][y] = true;
for(int i = ; i < ; ++i) {
int px = x + fx[i], py = y + fy[i];
if(!isdigit(mat[px][py]) || vis[px][py]) continue;
int wantlen = maxlen(px, py);
if(now.len + wantlen < ans.len) continue;
if(now.len + wantlen == ans.len) {
sort(can, can + wantlen);
tmp = now;
for(int i = wantlen - ; i >= ; --i) tmp.a[tmp.len++] = can[i];
if(tmp < ans) continue;
}
dfs(px, py);
}
if(ans < now) ans = now;
--now.len;
vis[x][y] = false;
} int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if(n + m == ) break;
memset(mat, , sizeof(mat));
for(int i = ; i <= n; ++i) scanf("%s", &mat[i][]);
ans.clear(); now.clear();
for(int i = ; i <= n; ++i) {
for(int j = ; j <= m; ++j)
if(isdigit(mat[i][j])) dfs(i, j);
}
ans.print();
}
}

UVA 11882 Biggest Number(搜索+剪枝)的更多相关文章

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

    题目大意:给出一个方格矩阵,矩阵中有数字0~9,任选一个格子为起点,将走过的数字连起来构成一个数,找出最大的那个数,每个格子只能走一次. 题目分析:DFS.剪枝方案:在当前的处境下,找出所有还能到达的 ...

  2. 【UVa】11882 Biggest Number(dfs+剪枝)

    题目 题目     分析 典型搜索,考虑剪枝. 统计一下联通分量. 1.本位置能够达到所有的点的数量加上本已有的点,还没有之前的结果长,直接返回. 2.当本位置能够达到所有的点的数量加上本已有的点与之 ...

  3. 湖南省第六届大学生程序设计大赛原题 F Biggest Number (UVA1182)

    Biggest Number http://acm.hust.edu.cn/vjudge/contest/view.action?cid=30851#problem/F 解题思路:DFS(检索)+BF ...

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

    Biggest Number 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 You have a maze with obstacles and non-zero di ...

  5. 湖南省第6届程序大赛第6题 Biggest Number

    Problem F Biggest Number You have a maze with obstacles and non-zero digits in it: You can start fro ...

  6. hdu 5887 搜索+剪枝

    Herbs Gathering Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  7. 【迭代博弈+搜索+剪枝】poj-1568--Find the Winning Move

    poj  1568:Find the Winning Move   [迭代博弈+搜索+剪枝] 题面省略... Input The input contains one or more test cas ...

  8. NOIP2015 斗地主(搜索+剪枝)

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 270  Solved: 192[Submit][Status] ...

  9. hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)

    题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...

随机推荐

  1. 大专生自学web前端前前后后

    先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ...

  2. Oracle数据库中 to_date()与to_char()函数的用法

    to_date() ,to_char()与24小时制表示法及mm分钟的显示: 一.在使用Oracle的to_date函数来做日期转换时,很多Java程序员也许会直接的采用“yyyy-MM-dd HH: ...

  3. 请对比 Exception 和 Error,另外,运行时异常与一般异常有什么区别?

    error指的是不可预料的错误,可能会导致程序宕机:而exception指的是在程序运行中可以预见的异常,而异常分为检查异常与一般异常,检查异常需要在程序中显示捕获并处理,一般异常可以通过程序编码来进 ...

  4. CF605A Sorting Railway Cars(递推)

    题目描述 An infinitely long railway has a train consisting of n cars, numbered from 1 to n (the numbers ...

  5. oracle 12.1的删除和创建公共用户问题

    版本12.1 ,cdb-rac模式 一个集群,4个节点,一个cdb,下面有12个pdb. os:linux 64 --- 删除用户 drop user c##test atler.log提示 ORA- ...

  6. Ajax之404,200等查询

    xmlhttp.readyState的值及解释: 0:请求未初始化(还没有调用 open()). 1:请求已经建立,但是还没有发送(还没有调用 send()). 2:请求已发送,正在处理中(通常现在可 ...

  7. mysql数据库的基本使用命令总结

    mysql数据库是一个常用的关系型数据库 关系型数据库核心元素有哪些? 主键:特殊字段,用来唯一标识记录的唯一性 字段:数据列 记录:数据行 数据表:数据行的集合 数据库:数据表的集合 安装.启动.停 ...

  8. C#中在WebClient中使用post发送数据实现方法

    很多时候,我们需要使用C#中的WebClient 来收发数据,WebClient 类提供向 URI 标识的任何本地.Intranet 或 Internet 资源发送数据以及从这些资源接收数据的公共方法 ...

  9. 为何企业钟爱H5响应式网站? html5响应式网站的优势与特点

    随着移动互联网时代的到来,H5响应式网站应运而生,并成功获得了商家.访客.搜索引擎等的青睐!越来越多的企业也选择了H5响应式建站,可为何企业钟爱H5响应式网站呢?难道传统网站不好吗?这个不能妄下结论, ...

  10. CacheManager源码分析

    计算rdd的某个分区是从RDD的iterator()方法开始的,我们从这个方法进入 然后我们进入getOrCompute()方法中看看是如何进行读取数据或计算的 getOrElseUpdate()方方 ...