HDOJ 1010 Tempter of the Bone
来源:互联网 发布:微信h5牛牛房卡版源码 编辑:程序博客网 时间:2024/05/16 11:29
题意:
n*m的矩阵,S是出发点,D是终点,
.是可以走的,X是不可以走的,T秒的时候D
才会被打开,否则就出不去,输出doggie最
后能否出去。
分析:奇偶剪枝
这个题目用一般的搜索无法完成,因为题目
要求在指定的时间内完成,所以只好一步一
步来啦,用DFS解决
但是如果直接用dfs结果会超时,网上说是用
一种奇偶剪枝的方法来间断搜索时间,
下面是剪枝的简单理论:
把map看作
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 需要奇数步
从 0->0 需要偶数步
那么设所在位置 (x,y) 与目标位置 (dx,dy)
如果abs(x-y)+abs(dx-dy)为偶数,则说明 abs(x-y)和 abs(dx-dy)的奇偶性相同,需要走偶数步
如果abs(x-y)+abs(dx-dy)为奇数,那么说明 abs(x-y)和 abs(dx-dy)的奇偶性不同,需要走奇数步
理解为 abs(si-sj)+abs(di-dj)的奇偶性就确定了所需要的步数的奇偶性!!
而 (ti-setp)表示剩下还需要走的步数,由于题目要求要在 ti时恰好到达,
那么 (ti-step) 与abs(x-y)+abs(dx-dy) 的奇偶性必须相同
因此 temp=ti-step-abs(dx-x)-abs(dy-y)必然为偶数!
一般这种dfs题目都需要一个map[][]记录个点的值,
一个record[][]记录一下某点是否走过(防止走重!!)
一个用于检测是否越界的函数isin()
其余的就是dfs函数的设计了。
//不知道我的代码哪里错了。。。就是wa了#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int maxn=10;int n,m,t,cnt,sx,sy,gx,gy;int dx[4]= {-1,0,0,1},dy[4]= {0,1,-1,0};char mp[maxn][maxn];int visit[maxn][maxn];bool dfs(int x,int y,int cnt){ int i,j,nx,ny; if(cnt==t&&mp[x][y]=='D') return true; if(x<1||x>n|y<1||y>m) return false; if(cnt>=t) return false; if(t-cnt<(abs(x-gx)+abs(y-gy))) return false; if((t-cnt-(int)(abs(x-gx)+abs(y-gy)))%2!=0) return false; //visit[x][y]=1; for(i=0; i<4; i++) { nx=x+dx[i]; ny=y+dy[i]; if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&!visit[nx][ny]&&mp[nx][ny]!='X') { visit[nx][ny]=1; if(dfs(nx,ny,cnt+1))//看看如果走这条路是否能走出去(true) return true; else visit[nx][ny]=0;//不能走出去的话就尝试下一种方式,就算是没走过这条路,故visit要标记成0,以免影响下一次的访问 } } return false;}int main(){ freopen("in.txt","r",stdin); while((scanf("%d%d%d",&n,&m,&t)!=EOF)&&(n||m||t)) { memset(visit,0,sizeof(visit)); int i,j; for(i=1; i<=n; i++) { getchar(); for(j=1; j<=m; j++) { scanf("%c",&mp[i][j]); if(mp[i][j]=='S') { sx=i; sy=j; } if(mp[i][j]=='D') { gx=i; gy=j; } } } visit[sx][sy]=1; if(dfs(sx,sy,0)) printf("YES\n"); else printf("NO\n"); } return 0;}
//AC代码:这是参考了别人的代码后来改过的。。。orz#include<iostream>#include<cmath>#include<cstring>#include<queue>#include <cstdio>int fangxiang[4][2]={{-1,0},{1,0},{0,-1},{0,1}};const int MAX=101;char map[MAX][MAX];int mark[MAX][MAX];int n,m,t;int start_x,start_y;int end_x,end_y;using namespace std;bool DFS(int x,int y,int step){int i,a,b;if(map[x][y]=='D'&&step==t)return true;if(x<1||x>n|y<1||y>m)return false;if(step>=t)//剪枝1:当step>=T时还没有找到D点return false;if(t-step<(abs(x-end_x)+abs(y-end_y)))//剪枝2:还需要的步数比理论上的最短距离还小return false;if((t-step-(int)(abs(x-end_x)+abs(y-end_y)))%2!=0) //剪枝3:比理论上的最短距离多出来的必是偶数return false;for(i=0;i<4;i++){a=x+fangxiang[i][0];b=y+fangxiang[i][1];if(a<=n&&a>=1&&b>=1&&b<=m&&map[a][b]!='X'&&!mark[a][b]) //判断三个条件:1.检验_x,_y是否越界。2.看vis[][]是否访问过。3.看map[][]是否是墙{mark[a][b]=1;if(DFS(a,b,step+1))return true;elsemark[a][b]=0;}}return false;}int main(){ //freopen("in.txt","r",stdin);int i,j;while(cin>>n>>m>>t&&(n||m||t)){memset(mark,0,sizeof(mark));for(i=1;i<=n;i++){for(j=1;j<=m;j++){ cin>>map[i][j]; if(map[i][j]=='S') { start_x=i; start_y=j; } if(map[i][j]=='D') { end_x=i;end_y=j; }}}mark[start_x][start_y]=1;if(DFS(start_x,start_y,0))cout<<"YES"<<endl;elsecout<<"NO"<<endl;}return 0;}
- hdoj 1010 Tempter of the Bone
- HDOJ 1010 Tempter of the Bone
- HDOJ 1010 Tempter of the Bone
- HDOJ 1010 Tempter of the Bone
- ACM HDOJ 1010 (Tempter of the Bone)
- HDOJ 1010 Tempter of the Bone
- HDOJ 1010 Tempter of the Bone
- HDoj-1010-Tempter of the Bone-DFS
- 【HDOJ 1010】Tempter of the Bone
- hdoj 1010 Tempter of the Bone
- hdoj 1010Tempter of the Bone【DFS】
- HDOJ 1010 Tempter of the Bone
- HDOJ 1010 Tempter of the Bone
- HDOJ 1010-Tempter of the Bone【dfs】
- HDOJ 1010 Tempter of the Bone
- HDOJ.1010 Tempter of the Bone (DFS)
- hdoj 1010 Tempter of the Bone
- HDOJ HDU 1010 Tempter of the Bone
- mysql 索引注意事项:表存储引擎的选择
- 挖掘机技术哪家强<numberTheory><欧拉函数>
- 关于C#窗体基本控件使用心得(1)
- Nsset NSdictionary的相关
- 2014.10.06
- HDOJ 1010 Tempter of the Bone
- C/C++命名控制
- linux中自启动服务说明
- Effective C++ 11-17
- KMP的理解
- 存储过程概述
- 第一篇嗯哼
- Centos 6.5 安装中文输入法
- 【Java.Web】JSP —— 标签库taglib —— 第三方标签库 —— 使用