hdu1010 Tempter of the Bone --DFS & 奇偶剪枝
2016-07-18 10:18
351 查看
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010
一:题意
一个n*m的迷宫,给定一个出发点,一个结束点,一条小狗需要在恰好第k秒走到结束点,如果可以输出YES,不然输出NO。
. 该点可以走
X 该点不可以走
S 起点
D 终点
二:分析
注意,这道题目是要恰好t时间到达,并不是在t时间内到达......
思路:剪枝+dfs
第一个剪枝我们可以想到,当剩下的步数大于剩下的时间的时候,狗是不能走到的;
接下来我们来第二个剪枝:
我们把map的奇偶性以01编号:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
我们发现从0走一步一定走到1,从1走一步一定走到0。
也就是说,如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步。
同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数。
也就是说,狗的坐标x、y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性。
两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可。
三:AC代码
一:题意
一个n*m的迷宫,给定一个出发点,一个结束点,一条小狗需要在恰好第k秒走到结束点,如果可以输出YES,不然输出NO。
. 该点可以走
X 该点不可以走
S 起点
D 终点
二:分析
注意,这道题目是要恰好t时间到达,并不是在t时间内到达......
思路:剪枝+dfs
第一个剪枝我们可以想到,当剩下的步数大于剩下的时间的时候,狗是不能走到的;
接下来我们来第二个剪枝:
我们把map的奇偶性以01编号:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
我们发现从0走一步一定走到1,从1走一步一定走到0。
也就是说,如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步。
同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数。
也就是说,狗的坐标x、y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性。
两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可。
三:AC代码
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 #include<iostream> #include<cstring> #include<algorithm> #include<cmath> using namespace std; char s[10][10]; int visited[10][10]; int dir[4][2] = { 0,1,-1,0,0,-1,1,0 }; int sx, sy;//起点坐标 int dx, dy;//出口坐标 bool flag; int n, m, k; void DFS(int x, int y, int c) { int i; int mx, my; if (x == dx&&y == dy)//不可写成if (x == dx&&y == dy&&c == k) { if (c == k) flag = true; return; } if (c >= k) return; if (s[x][y] != 'X') { for (i = 0; i < 4; i++) { mx = x + dir[i][0]; my = y + dir[i][1]; if (mx >= 0 && mx < n&&my >= 0 && my < m&&s[mx][my] != 'X' && !visited[mx][my])//判断坐标是否超出范围应该放在前面 { visited[mx][my] = 1; DFS(mx, my, c + 1); visited[mx][my] = 0; if (flag) return; } } } } int main() { int i, j; while (~scanf("%d%d%d", &n, &m, &k) && (n || m || k)) { for (i = 0; i < n; i++) { getchar(); for (j = 0; j < m; j++) { scanf("%c", &s[i][j]); if (s[i][j] == 'S') { sx = i; sy = j; } if (s[i][j] == 'D') { dx = i; dy = j; } } } getchar();//为什么注释这句就WA呢,不懂C的道道 flag = false; memset(visited, 0, sizeof(visited)); if (abs(dx - sx) + abs(dy - sy) > k || (dx + dy + sx + sy + k) % 2 == 1)//剪枝 { printf("NO\n"); continue; } visited[sx][sy] = 1; DFS(sx, sy, 0); if (flag) printf("YES\n"); else printf("NO\n"); } return 0; }
相关文章推荐
- hud 2502 月之数
- 数据库类
- hdu 5720 Wool
- EditText的inputType类型设置
- 更改Windows系统下的MessageBox按钮显示内容
- 二分图匹配——棋盘游戏 ( HDU 1281 )
- HDU 1096
- Studio android 快捷键文档
- C# Json转对象 序列化 反序列化
- mysql服务启动不了
- 在Linux主机上搭建SVN,用于同步提交修改,实现本地提交线上预览(SVN Hook功能实现)
- android 判断程序是首次(第一次)进入
- 【代码笔记】iOS-用户发布后能保存崩溃
- SAP错误问题汇总
- SCUACM 2016集训 7.15 N
- HDU 1494 跑跑卡丁车(简单DP)
- linux 定制自己的开机logo
- 检测某个元素是否存在
- 【代码笔记】iOS-用户发布后能保存崩溃
- 嵌入式 Linux进程间通信(十二)——多线程同步