假设当前已经到达(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 + 剪枝的更多相关文章

  1. Sticks(UVA - 307)【DFS+剪枝】

    Sticks(UVA - 307) 题目链接 算法 DFS+剪枝 1.这道题题意就是说原本有一些等长的木棍,后来把它们切割,切割成一个个最长为50单位长度的小木棍,现在想让你把它们组合成一个个等长的大 ...

  2. hdu 1044(bfs+dfs+剪枝)

    Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  3. POJ2688状态压缩(可以+DFS剪枝)

    题意:       给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路:       水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...

  4. soj1091 指环王 bfs+hash+剪枝

    原题链接http://acm.scu.edu.cn/soj/problem.action?id=1091 这题的主要解法就是搜索,我用的是bfs,用map将二维数组处理成字符串作为主键,到达当前状态的 ...

  5. Addition Chains POJ - 2248 (bfs / dfs / 迭代加深)

    An addition chain for n is an integer sequence <a0, a1,a2,...,am=""> with the follow ...

  6. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. POJ 3009 DFS+剪枝

    POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...

  8. poj 1724:ROADS(DFS + 剪枝)

    ROADS Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10777   Accepted: 3961 Descriptio ...

  9. DFS(剪枝) POJ 1011 Sticks

    题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...

随机推荐

  1. The server's host key is not cached in the registry. You have no guarantee that the server……

    使用putty中的pscp.exe ,可以通过脚本方式实现windows向linux上传文件,但pscp.exe第一次运行时必须手工输入确认信息,本文主要解决掉初次运行时的人工交互,彻底实现静默运行. ...

  2. springcloud(十二):使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪

    随着业务发展,系统拆分导致系统调用链路愈发复杂一个前端请求可能最终需要调用很多次后端服务才能完成,当整个请求变慢或不可用时,我们是无法得知该请求是由某个或某些后端服务引起的,这时就需要解决如何快读定位 ...

  3. MS SQL 日志记录管理

    MS SQL的日志信息/日志记录,可能对你来说,既熟悉又陌生,熟悉是因为你可能一直都在使用,查看.关注一些日志信息/记录,例如,作业历史记录:陌生是因为你可能从不关注日志信息/记录的管理,这里我一直用 ...

  4. Css3:transform变形

    transform 语法: transform      向元素应用 2D 或 3D 转换. transform : none | <<span class="title&quo ...

  5. CentOS 7 yum 安装 MySQL5.7

    1.下载 MySQL 官方的 Yum Repository ,官网地址:https://dev.mysql.com/downloads/repo/yum/ 从 MySQL 官网选取合适的 MySQL ...

  6. [JavaScript]自执行函数

    最近在接触mui的时候,遇到了一段代码: (function($, doc) { $.init({ statusBarBackground: '#f7f7f7' }); $.plusReady(fun ...

  7. 同一台机器上多个tomcat启动造成的内存溢出问题的解决方法。

    加下面这句话就行了,我是WIN10+双tomcat+nginx(本地站点),无压力.在编译器的vm option里面加哦. -server -Xms512m -Xmx1024m -XX:PermSiz ...

  8. Objective-C Runtime 文档翻译

    前言   Objective-C语言尽可能多的将许多决定从编译连接推迟到运行时.无论何时,它都尽可能的动态处理事件.这就意味着OC语言不仅仅需要编译器,还需要一个运行时系统来执行编译完成的代码.对于O ...

  9. CF487 E. Tourists [点双连通分量 树链剖分 割点]

    E. Tourists 题意: 无向连通图 C a w: 表示 a 城市的纪念品售价变成 w. A a b: 表示有一个游客要从 a 城市到 b 城市,你要回答在所有他的旅行路径中最低售价的最低可能值 ...

  10. WebSocket 示例

    websocket应运而生 在WebSocket规范提出之前,开发人员若要实现带有即时通信.实时数据.订阅推送等功能的应用实时性较强的功能,经常会使用的解决方法是 Comet. Comet是一种服务器 ...