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 相同长度的木棍不再搜索 ...
随机推荐
- CColor类封装
CColor类封装 Color.h #pragma once #include <sstream> #include <string> using namespace std; ...
- asp.net core如何自定义端口/修改默认端口
.net core运行的默认端口是5000,但是很多时候我们需要自定义端口.有两种方式 写在Program的Main方法里面 添加 .UseUrls() var host = new WebHostB ...
- lua版本的一个状态机
这个状态机http://www.cnblogs.com/flytrace/p/5587033.html的lua版本 -- LUA 有实现枚举值的好办法么 local sc_enum = { -- ev ...
- ansible 批量安装zabbix agentd客户端
目录结构 # tree /etc/ansible/ /etc/ansible/ ├── ansible.cfg ├── hosts ├── roles │ └── zabbix-agentd │ ...
- HTML5之Notification简单使用
var webNotification = { init: function() { if(!this.isSupport()) { console.log('不支持通知'); return; } t ...
- Core Animation 文档翻译—附录C(KVC扩展)
前言 关于CAAnimation和CALayer类,核心动画扩展了NSKeyValueCoding协议.这个扩展为一些keys添加了默认值,扩大了封装协议,添加了为CGpoint.CGRect.C ...
- bzoj 3597: [Scoi2014]方伯伯运椰子 [01分数规划 消圈定理 spfa负环]
3597: [Scoi2014]方伯伯运椰子 题意: from mhy12345 给你一个满流网络,对于每一条边,压缩容量1 需要费用ai,扩展容量1 需要bi, 当前容量上限ci,每单位通过该边花费 ...
- CodeChef Sereja and Game [DP 概率 博弈论]
https://www.codechef.com/problems/SEAGM 题意: n个数(可能存在相同的数),双方轮流取数.如果在一方选取之后,所有已选取数字的GCD变为1,则此方输.问:1 若 ...
- 基于Spring Boot,使用JPA调用Sql Server数据库的存储过程并返回记录集合
在上一篇<基于Spring Boot,使用JPA操作Sql Server数据库完成CRUD>中完成了使用JPA对实体数据的CRUD操作. 那么,有些情况,会把一些查询语句写在存储过程中,由 ...
- [Python Study Notes]实现对键盘控制与监控
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ...