UVA-11882 bfs + dfs + 剪枝
假设当前已经到达(x,y),用bfs判断一下还可以到达的点有maxd个,如果maxd加上当前已经经过的长度小于当前答案的长度就退出,如果相同,就将bfs搜索到的点从大到小排序,如果连最大序列都无法大于当前答案,就直接退出,否则继续搜索。
但是这题时间要求极高,不可以同时搜索同时更新答案,必须直到完成一种搜索(到达边界)才能更新答案,否则必定超时。
AC代码:
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; const int maxn = 30 + 5; char G[maxn][maxn]; int vis[maxn][maxn], d[maxn][maxn]; int n, m; int ans[maxn], len; //答案以及答案的长度 int a[maxn]; struct node{ int x, y; node(){ } node(int x, int y):x(x), y(y){ } }; const int dx[] = {1,-1,0,0}; const int dy[] = {0,0,1,-1}; int bfs(int x, int y, int cur){ //从cur开始保存 int c = cur; memcpy(d, vis, sizeof(vis)); queue<node>q; q.push(node(x, y)); d[x][y] = 1; while(!q.empty()){ node pos = q.front(); q.pop(); x = pos.x, y = pos.y; for(int i = 0; i < 4; ++i){ int px = x + dx[i], py = y + dy[i]; if(px < 0 || px >= n || py < 0 || py >= m) continue; if(G[px][py] == '#' || d[px][py]) continue; d[px][py] = 1; a[c++] = G[px][py] - '0'; q.push(node(px, py)); } } return c; } bool cmp(int a, int b){ return a > b; } void dfs(int x, int y, int cur){ int h = bfs(x, y, cur); if(h == cur) { //边界 int flag = 0; if(cur < len) return; else if(cur > len) flag = 1; else for(int i = 0; i < len; ++i){ if(a[i] < ans[i]) return; else if(a[i] > ans[i]) { flag = 1; break; } } if(flag) { len = cur; for(int i = 0; i < len; ++i) ans[i] = a[i]; //update } return; } if(h < len) return; else if(h == len){ sort(a + cur, a + h, cmp); int flag = 0; for(int i = 0; i < len; ++i) { if(a[i] < ans[i]) return; else if(a[i] > ans[i]) { flag = 1; break; } } if(!flag) return; } for(int i = 0; i < 4; ++i){ int px = x + dx[i], py = y + dy[i]; if(px < 0 || px >= n || py < 0 || py >= m) continue; if(G[px][py] == '#' || vis[px][py]) continue; a[cur] = G[px][py] - '0'; vis[px][py] = 1; dfs(px, py, cur + 1); vis[px][py] = 0; } } int main(){ while(scanf("%d%d", &n, &m) == 2 && n){ memset(ans, 0, sizeof(ans)); len = 0; for(int i = 0; i < n; ++i) scanf("%s", G[i]); for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) { if(G[i][j] == '#') continue; memset(vis, 0, sizeof(vis)); a[0] = G[i][j] - '0'; vis[i][j] = 1; dfs(i, j, 1); vis[i][j] = 0; } for(int i = 0; i < len; ++i){ printf("%d", ans[i]); } printf("\n"); } return 0; }
还有一种dfs代码,思路同上
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; const int maxn = 30 + 5; char G[maxn][maxn]; int vis[maxn][maxn], d[maxn][maxn]; int n, m; int ans[maxn], len; //答案以及答案的长度 int a[maxn]; struct node{ int x, y; node(){ } node(int x, int y):x(x), y(y){ } }; const int dx[] = {1,-1,0,0}; const int dy[] = {0,0,1,-1}; bool cmp(int a, int b){ return a > b; } int bfs(int x, int y, int cur){ int c = cur; memcpy(d, vis, sizeof(vis)); queue<node>q; q.push(node(x, y)); d[x][y] = 1; while(!q.empty()){ node pos = q.front(); q.pop(); x = pos.x, y = pos.y; for(int i = 0; i < 4; ++i){ int px = x + dx[i], py = y + dy[i]; if(px < 0 || px >= n || py < 0 || py >= m) continue; if(G[px][py] == '#' || d[px][py]) continue; d[px][py] = 1; a[c++] = G[px][py] - '0'; q.push(node(px, py)); } } return c; } void dfs(int x, int y, int cur){ a[cur++] = G[x][y] - '0'; int h = bfs(x, y, cur); if(h == cur) { //边界 int flag = 0; if(cur < len) return; else if(cur > len) flag = 1; else for(int i = 0; i < len; ++i){ if(a[i] < ans[i]) return; else if(a[i] > ans[i]) { flag = 1; break; } } if(flag) { len = cur; for(int i = 0; i < len; ++i) ans[i] = a[i]; //update } return; } if(h < len) return; else if(h == len){ sort(a + cur, a + h, cmp); int flag = 0; for(int i = 0; i < len; ++i) { if(a[i] < ans[i]) return; else if(a[i] > ans[i]) { flag = 1; break; } } if(!flag) return; } vis[x][y] = 1; for(int i = 0; i < 4; ++i){ int px = x + dx[i], py = y + dy[i]; if(px < 0 || px >= n || py < 0 || py >= m) continue; if(G[px][py] == '#' || vis[px][py]) continue; dfs(px, py, cur); } vis[x][y] = 0; } int main(){ while(scanf("%d%d", &n, &m) == 2 && n){ memset(ans, 0, sizeof(ans)); len = 0; for(int i = 0; i < n; ++i) scanf("%s", G[i]); for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) { if(G[i][j] == '#') continue; memset(vis, 0, sizeof(vis)); dfs(i, j, 0); } for(int i = 0; i < len; ++i){ printf("%d", ans[i]); } printf("\n"); } return 0; }
如有不当之处欢迎指出!
UVA-11882 bfs + dfs + 剪枝的更多相关文章
- Sticks(UVA - 307)【DFS+剪枝】
Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...
- hdu 1044(bfs+dfs+剪枝)
Collect More Jewels Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- POJ2688状态压缩(可以+DFS剪枝)
题意: 给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路: 水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...
- soj1091 指环王 bfs+hash+剪枝
原题链接http://acm.scu.edu.cn/soj/problem.action?id=1091 这题的主要解法就是搜索,我用的是bfs,用map将二维数组处理成字符串作为主键,到达当前状态的 ...
- Addition Chains POJ - 2248 (bfs / dfs / 迭代加深)
An addition chain for n is an integer sequence <a0, a1,a2,...,am=""> with the follow ...
- *HDU1455 DFS剪枝
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- POJ 3009 DFS+剪枝
POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...
- poj 1724:ROADS(DFS + 剪枝)
ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10777 Accepted: 3961 Descriptio ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
随机推荐
- 【转】linux shell 逻辑运算符、逻辑表达式
shell的逻辑运算符 涉及有以下几种类型,因此只要适当选择,可以解决很多复杂的判断. 一.逻辑运算符 逻辑卷标表示意思 1.关于档案与目录的侦测逻辑卷标! -f常用!侦测‘档案’是否存在 eg: ...
- TensorFlow-相关 API(学习笔记 )
1.tf.nn.conv2d conv2d( input, filter, strides, padding, use_cudnn_on_gpu=True, data_format='NHWC', n ...
- Zabbix3.4部署
Zabbix简介 zabbix(音同 zæbix)是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活 ...
- event跨进程通信
event天生的弱势,只有mutex可以感知丢失,就是将另一个进程关闭了,event无法感知. event1: #include <stdio.h> #include <stdlib ...
- github上最好的开源MMORPG - stendhal
Stendhal is a fully fledged multiplayer online adventures game (MORPG). It is completely open source ...
- HTTP协议篇(一):多工、数据流
管道机制.多工 管道机制(Pipelining) HTTP 1.1 引入了管道机制(Pipelining),即客户端可通过同一个TCP连接同时发送多个请求.如果客户端需要请求两个资源,以前的做法是在同 ...
- xBIM IFC 墙壁案例
目录 xBIM 应用与学习 (一) xBIM 应用与学习 (二) xBIM 基本的模型操作 xBIM 日志操作 XBIM 3D 墙壁案例 xBIM 格式之间转换 xBIM 使用Linq 来优化查询 x ...
- BZOJ 4276: [ONTAK2015]Bajtman i Okrągły Robin [线段树优化建边]
4276: [ONTAK2015]Bajtman i Okrągły Robin 题意:\(n \le 5000\)个区间\(l,r\le 5000\),每个区间可以选一个点得到val[i]的价值,每 ...
- 使用tcp+select实现客户端与客户端的通信
使用多路复用实现客户端与客户端进行通信: 原理:客户端只要一连上服务器,立马给服务器发送用户名,然后在服务端将newsocketfd存放在同一个结构体中,客户端先给服务器发送数据,然后通过服务器转发给 ...
- 携程Apollo(阿波罗)配置中心用户管理和部门管理
Apollo是配置管理系统,会提供权限管理(Authorization),理论上是不负责用户登录认证功能的实现(Authentication).所以Apollo定义了一些SPI用来解耦,Apollo接 ...