Uva11882 Biggest Number 【dfs回溯+bfs剪枝】【习题7-15】
来源:互联网 发布:如何找pdf 知乎 编辑:程序博客网 时间:2024/05/21 11:36
题目:Biggest Number
题意:
在一个R行C列(2≤R,C≤15,R*C≤30)的矩阵里有障碍物和数字格(包含1~9的数字)。 你可以从任意一个数字格出发,每次沿着上下左右之一的方向走一格,但不能走到障碍格中,也不能重复经过一个数字格,然后把沿途经过的所有数字连起来,问:能得到的最大整数是多少?
思路:
还是老套路,dfs寻找所有路径,累计筛选最大的数即可,恩,很简单嘛。。。提交,TLE,呵呵,数字太大了!所以剪枝来了。。。
本题的连接数字已经超出了long long型,所以需要用字符串,所以首先比较的是长度,长度越长即越大!!!
剪枝1:当前已经连接的数的个数+还可连接的数的个数 < 当前最优解的长度,直接剪枝,没有必要再搜索下去!
怎么找还可连接的数的个数呢? 利用bfs,使用当前的标记数组,搜索出还可连接的个数即可。
剪枝2:当前已经连接的数的个数+还可连接的数的个数 == 当前最优解的长度时,比较大小,小直接剪掉。只比较当前连接的数的长度这些数字,将当前的串加上一个比数字字符大的字符即可。因为有可能当前串和最优解的都相等,但最优解串长,就直接认为是最优解大了,其实当前还不确定,所有再当前串的下一位加一个大于数字的字符,这样避免了相等也被剪枝的情况!
筛选最优解:每次递归时将当前串进行与最优解比较长度,如果相等的话再比较大小。
参考:ECNU_ZR博客
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;typedef long long LL;const int maxn = 20 + 5;const int dx[] = {0,0,1,-1};const int dy[] = {1,-1,0,0};char g[maxn][maxn];int visitD[maxn][maxn],visitB[maxn][maxn];int r,c;string ans,temp;struct Node{ int x,y; Node(int x = 0,int y = 0):x(x),y(y){}};queue<Node>Q;inline bool scope(int tx,int ty){//判断边界 if(tx < 0 || tx >= r || ty < 0 || ty >= c) return true; return false;}int bfs(int x,int y){//查找当前(x,y)开始还可以连接几个数字 memcpy(visitB,visitD,sizeof(visitD));//将当前dfs标记数组赋给bfs标记数组 visitB[x][y] = 1;//标记起点 while(!Q.empty()) Q.pop();//清空队列 Node pre; Q.push(Node(x,y));//将起点入队 int cnt = 0;//记录经过几个点 while(!Q.empty()){ pre = Q.front();Q.pop(); for(int i=0;i<4;i++){ int tx = pre.x + dx[i] , ty = pre.y + dy[i]; if(scope(tx,ty)) continue; if(g[tx][ty] != '#' && !visitB[tx][ty]){ visitB[tx][ty] = 1; Q.push(Node(tx,ty)); cnt++;//记录连接到的数字个数 } } } return cnt;//返回剩余的连接个数}void update(const string &s){//更新最优解:当前长度长或长度相等数字大时更新 if(s.size() > ans.size() || s.size() == ans.size() && s > ans) ans = s;}void dfs(int d,int x,int y,string sum){//回溯枚举所有连接路径 int len = bfs(x,y);//当前点还可连接的数的个数 if(d + len < ans.size()) return;//剪枝:当前的长度+还可连接的长度 < 最优值的长度,没有必要再进行下去 if(d + len == ans.size() && sum+"a" < ans) return;//剪枝:长度相等,但没有最优解大,没有不必了! update(sum);//更新最优解 for(int i=0;i<4;i++){ int tx = x + dx[i] , ty = y + dy[i]; if(scope(tx,ty)) continue; if(!visitD[tx][ty] && g[tx][ty] != '#'){ visitD[tx][ty] = 1; dfs(d+1,tx,ty,sum + g[tx][ty]); visitD[tx][ty] = 0; } }}inline void solve(){ ans = ""; for(int i=0;i<r;i++) for(int j=0;j<c;j++) if(g[i][j] != '#'){ memset(visitD,0,sizeof(visitD)); visitD[i][j] = 1;//注意:将起点标记 temp = g[i][j]; dfs(1,i,j,temp); } cout << ans << endl;}int main(){ while(scanf("%d%d",&r,&c)!=EOF && r && c){ for(int i=0;i<r;i++) scanf("%s",g[i]); solve(); } return 0;}
0 0
- Uva11882 Biggest Number 【dfs回溯+bfs剪枝】【习题7-15】
- UVA11882 Biggest Number 强剪枝
- UVA11882 Biggest Number
- UVA 11882 Biggest Number (dfs搜索+bfs 剪枝)
- UVA 11882 Biggest Number (搜索+剪枝(dfs+bfs))
- 11882 - Biggest Number(DFS + 剪枝)
- UVa 11882:Biggest Number(DFS+剪枝)
- 第六届湖南省省赛 Biggest Number(DFS+BFS,巧妙剪枝)
- 习题7-15 最大的数 UVa11882
- nyoj 667 Biggest Number 搜索 减枝 dfs bfs
- NBUT [1464] Biggest Number dfs
- uva11882 最大的数 bfs 遍历估价剪枝
- 【搜索+强剪枝】UVA-11882 - Biggest Number
- Biggest Number(刘汝佳,搜索+剪枝)
- dfs + 回溯 +剪枝
- Uva307 Sticks 【dfs+剪枝】【习题7-14】
- Uva225 Golygons 【dfs回溯】【习题7-2】
- 习题7-1:消防车(dfs+回溯)
- PHP开发学习笔记之上传多文件
- 分享一些前端开发中最常用的JS代码片段以及理解 JS闭包
- “玲珑杯”ACM 热身赛 # 2.5 A-B (数论)
- kube-controller原理解析
- 基于Gabor滤波器的车道线识别
- Uva11882 Biggest Number 【dfs回溯+bfs剪枝】【习题7-15】
- nyoj 143 第几是谁(康拓展开的逆运算)
- 判断输入的日期字符串是否小于当前日期
- 新的一年面试开始,某公司机试题。
- 大数据工程师面试题(四)
- eclipse使用git
- android应用开发代码规范
- Xshell/Xftp安装与使用
- JVM运行内存分配——拨云见日