HDU1010 Tempter of the Bone(回溯 + 剪枝)
本文链接:http://i.cnblogs.com/EditPosts.aspx?postid=5398734
题意:
输入一个 N * M的迷宫,这个迷宫里'S'代表小狗的位置,'X'代表陷阱,‘D’代表门,‘.’代表可行走的地方,小狗每次可以选择往周围的四个方向行走,问这个小狗能否正好T步找到门。
思路:
利用回溯 + 剪枝,这道题剪枝特别重要。
剪枝一:
可以把图看成这样:
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
则假设从点 a(i + j,横纵坐标之和) 走到点 b(i + j) ,如果 a 和 b 的奇偶性相同,那么从 a 到 b 必须是偶数步.如果 a 和 b 的奇偶性不同则走过的步数必须是奇数步。所以 当 (a + b + T)为奇数时一定不能恰好到达。
剪枝二:
如果已经找到答案就没有要继续求解。
剪枝三:
T大于从S到D的最长路径,小于从S到D的最短路径,则无解。
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
using namespace std; const int MAXN = ;
char Gra[MAXN][MAXN];
int stepX[] = {, , , -};
int stepY[] = {-, , , };
int N, M, T;
int cnt;
int beginX, beginY, endX, endY;
int OK; int check(int x, int y)
{
if(Gra[x][y] == 'O') return ; // 走到了已经走过的路
if(Gra[x][y] == '*') return ; //走出了边界
if(Gra[x][y] == 'X') return ; //走到了墙
if(cnt > T) return ; //在此时走的步数已经大于总步数则
return ;
} void backtrack(int x, int y)
{
if(x == endX && y == endY ) //到达终点
{
if(cnt == T) //找到了答案
OK = ;
}
else
{
for(int i = ; i < ; i++) //在这点一共有四种选择(状态)
{
int tx = x + stepX[i];
int ty = y + stepY[i];
if(check(tx, ty)) //检查所选择的状态是否合理
{
++cnt; //记录走过的步数
Gra[tx][ty] = 'O'; //标记走过的地方
if(OK) return; //尤为重要的剪枝 ,如果找到答案,就不用继续递归,
backtrack(tx, ty);
Gra[tx][ty] = '.'; //恢复现场
--cnt; }
}
}
} int main()
{
//freopen("in.txt","r", stdin);
while(~scanf("%d%d%d",&N, &M, &T) && N)
{
getchar();
beginX = beginY = endX = endY = ;
memset(Gra, '*', sizeof(Gra));
for(int i = ; i <= N; i++)
{
for(int j = ; j <= M; j++)
{
scanf("%c",&Gra[i][j]);
if(Gra[i][j] == 'S')
beginX = i, beginY = j;
if(Gra[i][j] == 'D')
endX = i, endY = j;
}
getchar();
}
OK = ;
if( (T > M * N) || ( T < (abs(beginX - endX) + abs(beginY - endY)) ) || ( (beginX + beginY + endX + endY + T) & ))//剪枝二、三
{
printf("NO\n"); continue;
}
cnt = ;
Gra[beginX][beginY] = 'O';
backtrack(beginX, beginY);
if(OK) printf("YES\n");
else printf("NO\n");
}
return ;
}
HDU1010 Tempter of the Bone(回溯 + 剪枝)的更多相关文章
- HDU1010:Tempter of the Bone(dfs+剪枝)
http://acm.hdu.edu.cn/showproblem.php?pid=1010 //题目链接 http://ycool.com/post/ymsvd2s//一个很好理解剪枝思想的博客 ...
- TZOJ 1221 Tempter of the Bone(回溯+剪枝)
描述 The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked i ...
- hdu1010 Tempter of the Bone —— dfs+奇偶性剪枝
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 Tempter of the Bone Time Limit: 2000/1000 MS (Ja ...
- Hdu1010 Tempter of the Bone(DFS+剪枝) 2016-05-06 09:12 432人阅读 评论(0) 收藏
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU1010 Tempter of the Bone【小狗是否能逃生----DFS奇偶剪枝(t时刻恰好到达)】
Tempter of the Bone Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- hdu1010 Tempter of the Bone(深搜+剪枝问题)
Tempter of the Bone Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission( ...
- hdu 1010 Tempter of the Bone 奇偶剪枝
如果所给的时间(步数) t 小于最短步数path,那么一定走不到. 若满足t>path.但是如果能在恰好 t 步的时候,走到出口处.那么(t-path)必须是二的倍数. 关于第二种方案的解释 ...
- HDU1010 --- Tempter of the Bone(dfs+剪枝)
小明做了一个很久很久的梦,醒来后他竟发现自己和朋友在一个摇摇欲坠的大棋盘上,他们必须得想尽一切办法逃离这里.经过长时间的打探,小明发现,自己所在的棋盘格子上有个机关,上面写着“你只有一次机会,出发后t ...
- HDU1010 Tempter of the Bone
解题思路:相当经典的一题,回溯,具体细节处理见代码. #include<cstdio> #include<cstring> #include<algorithm> ...
随机推荐
- copyEvens
public int[] copyEvens(int[] nums, int count) { int newIndex=0; int i=0; int newArray[] = new int[co ...
- Mybatis基本用法
搭建mybatis环境 1, 导入需要的jar包 mybatis-*.*.*.jar ojdbc6.jar 2, 配置mybatis的总配置文件: mybatis-config.xml 配置根标签 & ...
- ASP.NET Core [3]:进入HttpContext的世界(笔记)
原文链接:http://www.cnblogs.com/RainingNight/p/httpcontext-in-asp-net-core.html HttpContext是ASP.NET中的核心对 ...
- [oldboy-django][2深入django]form表单clean_xx, clean完成数据验证+ form错误信息
form后台生成form里面的Input标签,以及设置Input的属性 # 需求 后台生成form里面的input标签,并设置input标签的属性, class RegisterForm(Form): ...
- ZOJ 3544 / HDU 4056 Draw a Mess( 并查集好题 )
方法参见:http://blog.acmol.com/?p=751 从最后一个线段开始倒着处理(因为之后的线段不会被它之前的线段覆盖),把这条线段所覆盖的所有线段编号合并到一个集合里,并以最左边线段编 ...
- struct&&class 空的大小
#include using namespace std; class ClassA { }; class ClassB { private: int b; }; class ClassC : pub ...
- 【Android】实验8 SQLite数据库操作2016.5.12
实验8 SQLite数据库操作 [目的] 设计一个个人通讯录,掌握Android平台下的数据库开发,该个人通讯录主要包括联系人列表和联系人详细信息等界面. [要求] 程序主界面是通讯录的目录显示手机 ...
- A - 最长上升子序列
A - 最长上升子序列 Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others) Problem De ...
- easyUI layout
layout是一个容器,它有5个区域:north(北丐),south(南帝),east(东邪),west(西毒),center(中神通),像不像金庸的天龙八部,中间区域的panel是必须的, 周边区域 ...
- Codeforces Round #388 (Div. 2) 749E(巧妙的概率dp思想)
题目大意 给定一个1到n的排列,然后随机选取一个区间,让这个区间内的数随机改变顺序,问这样的一次操作后,该排列的逆序数的期望是多少 首先,一个随机的长度为len的排列的逆序数是(len)*(len-1 ...