hdu-1010 dfs+剪枝
思路:
剪枝的思路参考博客:http://www.cnblogs.com/zibuyu/archive/2012/08/17/2644396.html 在其基础之上有所改进
题意可以给抽象成给出一个图,让你求S点到D点之间是否存在一条长度为T的道路。求两地之间的距离用的是dfs,而dfs在这里的关键是找到回溯的条件,就是当到达D点并且剩余步数为0时,则符合题意的要求,由于我们只需要知道这样一条长度为T的路径是否存在,因此当我们发现存在的时候,只需要将一个全局flag给设置为1即可,然后从此之后的所有dfs调用都直接return。
另外关键的问题就是剪枝。当我们的思路走到求两个点的距离时,我们应当“俯视”一下——这两个点S和D,他们之间的距离从整个图上来看有什么性质。在这里有这样的规律:aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI8AAADQCAIAAACx2aXmAAAHrElEQVR4nO2dPZKrOhBG7/bYCAW7IKCKRZAQsAMyEhbglIiUeLJZwA1Af0gCMQabDz7XCaZmQMZ91LK4r5v37/dnJCj8+/oVkHBoCwnaQoK2kDjWVlNEWTf/4Hol5XDKx3jVifP9tFfemNcZ1/34+zP+tpn5p0tznq05HF0epdVrjstZtmx5QoYTdSWvOomK9vsaPm2ry/WJnH3YlvHuW2ltXNJH14DL2Pr9GUNzqy/TKK4rEam8UVGTi1Jfplr0xPRviiiuW/mn6b3sa9hKrPkAkVifS3pUW0LM5Gn6ebLYT6erBarLpZjp63CWNFTx9PNQxVuZJTNm+oaL634cqlhdw1NtRVEUpVW5tsvoy9RIF+fPGm2m29IOWB7f5c4vITV1hiqOojhN4rp/1YlITWs9vOw32eHfW8vcMoKur4T9MpROGeLlHPZVJyJxzZXTeslEnzyZ1/bg3PLbkmzbkjkq9wJrtrpcrXLruSXOoq0QW1NcNm0twhe6Eq7cdW3ZMl/zLLkeH7U1f7GH2JL7vXmJU7sP+SeRUoYt5tZhtub9YcD3lnb/lHXmClnkIhWWIX4jt55ma46v+NjuXfW7QfFsGjVbzK3rsG7r/tAWEli2ng5tIUFbSNAWErSFBG0hQVtI0BYStIUEbSFBW0jQFhK0hQRtIUFbSNAWErSFBG0hQVtI0BYSn7elqv62SmLXW+GuNs4Nbb3qRDZpNcVagOYgeqJztXFuacuo0vWWXc6Vo0lW+Oby1ca5p61FOPoydfU3DlXZ/YxrK8/VxrmlraGKreisdJ16o3O1cWiLtr5tK3Dl2Y7O1ca5p61FODaaO/zRudo497S1Y8e8Hp2rjXNPW+P17mp5d0zOgbaQoC0kaAsJ2kKCtpCgLSRoCwnaQoK2kKAtJGgLiW/ZwvoX2/BxbmgLq55p139VuZctvHqmsHHuagutnmlfNcC9bAlgKmR2jkNbtHVZW5erZ+JKiFTPtG+cp9m6XD3Tg3fwAdEZv3FXy7tjcjS0hQRtIUFbSNAWErSFBG0hQVtI0BYStIUEbSFBW0jQFhLsO2bf8boqyOozPpULpPqMT+WSwQKoPuNTuWR0gOqZaIu2LmsLvPrsabawq8+eZgu7+uxxtsbr3dXy7picA20hQVtI0BYStIUEbSFBW0jQFhK0hQRtIUFbSNAWEuw7PnacG9rCqmd6cE8/Xj0Tn8qFVM/EZ9EAVcjwOU8XjDJt/cnW5eqZuBIi1TPxqVxQ9UwP3sEHRGf8xl0t747J0dAWErSFBG0hQVtI0BYStIUEbSFBW0jQFhK0hQRtIcFOVnayrquCrGfic55A6pn4nCcZLIB6Jj7nSUYHqEKGtmjrsrbA65meZgu7nulptrDrmR5na7zeXS3vjsk50BYStIUEbSFBW0jQFhK0hQRtIUFbSNAWErSFBG0hQVtI0BYStIUEbSFBW0jQFhK0hQRtIUFbSNAWErtsNYVZytrlX35K1XQNG6+pXLDNto7zNvwMVSxqDk36Mp2qRdtsOqDLpxGWgXKfu/85h2fbOuTpYzsK+YYq3n4jGWX3yOqa/S8Rh8lTm0V5I1SNv32ZOu3qtcCn27LeQF3fiqp3n+y32ua2J2NCs9DS75tqc1+X9V7L30tDS1vGKyQ479pae4/AZ3Orme4Jx0qbmzWmlVsqe9TVOnNLrGYaTSFirQTYlzrNGHVuU8hPvfhoH88tvWFGT52AUK5c3zzRln8NbXOTGZaUXRWn1UumkW4u2JZcCV1X22aRFoQuj6IorqvpAuK6H4cqSxNxwGIGfNSWCIoInJp6zuN3P+15dmYfc0wBeuBK6FzfnAd3ubaFyRs159psmhZyfoSPeZiteWvUl+kkrC/TpKxzr4C/PptbW0m2bG0LmF6LKWXmxy7sXYxjxzjnrv1BtGwzF56gzdEuW2pP0WZRUtbTxBHzyIFnJTQmmv45D8gt39Y5ZJune22K5R/mYfWwOuaKtsCmSbycJfp81YIzVLF71X3DlhkItey6ZtDyGJe85ZGR/4rXbG0uMr5Nh/4ba8KZH0r7IGYSGKMZey47fZ1Ly/TBtxbA3bbMq2wKfUvt1RC2g/fvCUNtqbfIxK5kjstihRmqLFVJlnVtZuncY6tvul7LWmNbaP/GludcSN63ZWSJI+5d7ttunH53vMuWcZb2sgYPWgn1I4tciFcz4FUny7Bo7/uX/2FDkC3tLti5bghhwRl9IF5blbmDNe9GHbNtPRXUbbi1fe/Ni7F/k5SDPP29EPFfdZGgLSRoCwnaQoK2kKAtJGgLCdpCgraQoC0kaAsJ2kKCtpCgLSRoCwnaQoK2kKAtJGgLCdpCgv1bxksVP81lXnbxkzYm+7fePP2I/q15nChvtOIndaRRSs3+rR2nn9W/Jd2s5Rb7t3aeflL/VptFy7pxT279sH9r7+mn9G9JW2tZyP4tVRT9p4YiLzv6t5LYCqXjG479W6NcSUJOP6N/q8uzbp74a31EMmvZv7V2+pbpI/q3NFt6A0DRjr/9axBJw/6t3aef0r/ltzVNWbHEsX9r5+mn9G/ptqrlVlutK+zf2nv6Kf1bjtySf1IroS6G/VtBnNK/5bUlN/Rx3bN/i6xCW0jQFhK0hcR/Hojviubvz7MAAAAASUVORK5CYII=" alt="" />
也就是一开始给我们的两个起始点S和D,如果他们之间距离的最小值的奇偶性和T的奇偶性是不同的,那么在一开始我们就可以判断——“NO”!因为0->0和1->1无论怎么走需要的步数都为偶数步,1->0或0->1无论怎么走需要的步数都为奇数步。利用这点,从一开始我们就可以进行奇偶剪枝。
还有一个并不影响最后AC但是也值得思考的一个剪枝,就是在一开始的时候给定图可走的点数就小于T,那就直接不需要考虑。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std; char G[][];//G[n][m]
int dx,dy;
int n,m,t;
int dir[][] = {{,-},{,},{,},{-,}};
int flag; void dfs(int cx,int cy,int step) {
//now we're at (cx,cy),there're "step" steps left to get to (dx,dy)
if(cx<||cx>n||cy<||cy>m)
return;
if(flag) return;
if(cx==dx&&cy==dy&&step==) {
flag = ;
return ;
}
for(int i = ;i < ;i++) {
int nx = cx+dir[i][];
int ny = cy+dir[i][];
if(nx<||ny<||nx>n||ny>m) continue;//(1)over-border
if(G[nx][ny] == 'X') continue;//(2)can't get to(nx,ny)
G[cx][cy] = 'X';
dfs(nx,ny,step-);
if(flag) return;
G[cx][cy] = '.';
}
} int main()
{
int sx,sy;
int i,j;
while(scanf("%d%d%d",&n,&m,&t)&&(n!=||m!=||t!=)) {
int wall = ;
for(i=;i<=n;++i)
{
scanf("%s",G[i]+);
for(j=;j<=m;++j)
{
if(G[i][j]=='S')
{
sx=i;
sy=j;
}
if(G[i][j]=='D')
{
dx=i;
dy=j;
}
if(G[i][j]=='X') wall++;
}
}
//cut branches-1
if((abs(sx-dx)+abs(sy-dy))% != t%) {
cout<<"NO"<<endl;
continue;
}
//cut branches-2
if(n*m-wall < t) {
cout<<"NO"<<endl;
continue;
}
flag = ;
dfs(sx,sy,t);
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return ;
}
hdu-1010 dfs+剪枝的更多相关文章
- Tempter of the Bone HDU 1010(DFS+剪枝)
Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, ...
- poj 1564 Sum It Up | zoj 1711 | hdu 1548 (dfs + 剪枝 or 判重)
Sum It Up Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Sub ...
- hdu 4109 dfs+剪枝优化
求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己添加的)出发,0到1~n个节点之间的距离为1.mt[i]表示从0点到第i个节点眼下所得的最长路径 #include<iost ...
- HDU 1010 (DFS搜索+奇偶剪枝)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意:给定起点和终点,问刚好在t步时能否到达终点. 解题思路: 4个剪枝. ①dep&g ...
- hdu 1010(DFS) 骨头的诱惑
http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意从S出发,问能否在时间t的时候到达终点D,X为障碍 需要注意的是要恰好在t时刻到达,而不是在t时间 ...
- HDU 5113 dfs剪枝
题意:告诉格子规格,颜色个数,以及每个颜色能涂得格子数目,问是否能够实现相邻两个格子的颜色数目不相同. 分析:因为数据很小,格子最多是5 * 5大小的,因此可以dfs.TLE了一次之后开始剪枝,31m ...
- hdu 1010 dfs搜索
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- hdu 1518 dfs+剪枝
题目大意:几根棒子能否组成一个正方形 Sample Input3 //测试组数4 1 1 1 1 //棒子数目以及每根棒子的长度5 10 20 30 40 508 1 7 2 ...
- hdu 1010:Tempter of the Bone(DFS + 奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU 1010 Tempter of the Bone --- DFS
HDU 1010 题目大意:给定你起点S,和终点D,X为墙不可走,问你是否能在 T 时刻恰好到达终点D. 参考: 奇偶剪枝 奇偶剪枝简单解释: 在一个只能往X.Y方向走的方格上,从起点到终点的最短步数 ...
随机推荐
- 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程
第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...
- codevs 1200 同余方程 (Extend_Eulid)
/* 扩展欧几里得 ax%b==1 -> ax-by==1 求不定方程的一组解 使x为最小正整数解 */ #include<iostream> #include<cstdio& ...
- ASP.NET-FineUI开发实践-11
我用实例项目写了个子父页面传值,算是比较灵活的写法,可以把js提取出来写成包,然后调用,我先一步一步写,为有困难的朋友打个样. 先画个页面: 上面是个查询用的表单,底下是表格,内存分页,用到了VBox ...
- Windows XP CD 函数不正确
参考这篇文章:http://support.hp.com/cn-zh/document/c00760286 一,在设备管理中查看,如果刻录机名称中含 ROM,则需确认设备是否可写 二,若确定设备可写, ...
- WorkBook的SaveAs方法 2
-----转载:http://blog.csdn.net/zyming0815/article/details/5939104 语法 声明Sub SaveAs ( _ Filename As ...
- Android 开发笔记——对应用进行单元测试
在实际开发中,开发android软件的过程需要不断地进行测试.而使用Junit测试框架,是正规Android开发的必用技术, 在Junit中可以得到组件,可以模拟发送事件和检测程序处理的正确性. 第一 ...
- for update和for update nowait的区别和使用
首先,for update 和for update nowait 是对操作的数据行进行加锁,在事务提交前防止其他操作对数据的修改. for update 和for update nowait主要区别在 ...
- Oracle 用户(user)和模式(schema)的区别
概述: (一)什么Oracle叫用户(user): A user is a name defined in the database that can connect to and access ob ...
- iOS开发常用的第三方框架
1. AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项目.AFNetworking是一个轻量级的iOS.Mac OS X网络通信类库,现在是G ...
- Hibernate 环境搭建
Hibernate 工作流程 1.创建工程并导包 2.在src根目录下创建配置文件:hibernate.cfg.xml(也可以创建在src其他文件夹下,但是在后面的配置中,需要指明路径) <?x ...