HDU 1010 Tempter of the Bone 经典深搜~DFS
2012-08-16 00:02
357 查看
杭电1010题经典的深搜问题 值得一看~~
解释
一.奇偶剪枝
例如 4*4的矩阵
1 0 1 0
0 1 0 1
1 0 10
0 1 0 1
由1到1 由0到0必走偶数步
由1到0 由0到1必走偶数步
所以 根据这个和时间来判断是否成立
例如
4 4 5
S . X .
. . X .
. . X .
D . . .
代码:
int dis=abs(bx-ex)+abs(by-ey);
if((dis+t)%2!=0){printf("NO\n");continue;} //奇偶剪枝
S处于1的位置 D处于0的位置 则必须经历奇数的步骤才可以到达 3,5,7,都可以 到达
如果给的时间是4,6一定不行
二:位置剪枝
nx>=0&&nx<n&&ny>=0&&ny<m
即所给的查找位置不能超过地图的范围
三:
dis>t-time
剩余的时间到达不了既定的位置;
如
4 4 3
.S X .
. . X .
. . X .
.D . .
就会排除向左走的情况
如果想左走
dis=4 t=3 time由0变成了1 会减掉这种情况。
四 切记切记要对 代码中我用红线标注的注意 一定要重新进行初始化
如果不重新初始化 还用x,y的话会对其产生影响 是带入子函数的值变化。
正确代码:
post code:
下附自己的测试样例
4 4 5
S.X.
..X.
..XD
....
NO
3 4 5
S.X.
..X.
...D
YES
3 4 10
S...
..X.
..D.
YES
3 4 6
....
..X.
.SXD
YES
对四的解释
样例
post code:
解释
一.奇偶剪枝
例如 4*4的矩阵
1 0 1 0
0 1 0 1
1 0 10
0 1 0 1
由1到1 由0到0必走偶数步
由1到0 由0到1必走偶数步
所以 根据这个和时间来判断是否成立
例如
4 4 5
S . X .
. . X .
. . X .
D . . .
代码:
int dis=abs(bx-ex)+abs(by-ey);
if((dis+t)%2!=0){printf("NO\n");continue;} //奇偶剪枝
S处于1的位置 D处于0的位置 则必须经历奇数的步骤才可以到达 3,5,7,都可以 到达
如果给的时间是4,6一定不行
二:位置剪枝
nx>=0&&nx<n&&ny>=0&&ny<m
即所给的查找位置不能超过地图的范围
三:
dis>t-time
剩余的时间到达不了既定的位置;
如
4 4 3
.S X .
. . X .
. . X .
.D . .
就会排除向左走的情况
如果想左走
dis=4 t=3 time由0变成了1 会减掉这种情况。
四 切记切记要对 代码中我用红线标注的注意 一定要重新进行初始化
如果不重新初始化 还用x,y的话会对其产生影响 是带入子函数的值变化。
正确代码:
post code:
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> int n,m,t,bx,by,ex,ey,flag=0;; char map[10][10]; int visit[10][10]; int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0}; void dfs(int x,int y,int time) { int i; if(flag==1){return;} //查找成功后返回 if(time==t){if(x==ex&&y==ey){flag=1;return;}} //在给定的时间时找到出口 if(t<=time){return;} //超出时间未找到 放弃 int dis; dis=abs(ex-x)+abs(ey-y); //查找的位置 与终点的距离 if((dis>t-time)||(dis+t-time)%2!=0) //1是剩余的时间到不了既定位置 2是运动中奇偶 剪枝 {return;} //上一句话是关键的剪枝 for(i=0;i<4;i++) { int nx=x+dx[i]; //切记一定要重新定义查找的地点 keykeykey int ny=y+dy[i]; if(nx>=0&&nx<n&&ny>=0&&ny<m&&visit[nx][ny]!=1&&map[nx][ny]!='X') { //前四个 位置剪枝 第五个 不走返回路 第六个 不走障碍路 visit[nx][ny]=1; //标记已经过 dfs(nx,ny,time+1); //注意营卫time+1 time++是错误的 visit[nx][ny]=0; //将经过 回溯为 未经过 } } } int main() { int i,j,temp,dis,ji; while(scanf("%d %d %d",&n,&m,&t)) { ji=1; for(i=0;i<10;i++) //对visit数组进行初始化 for(j=0;j<10;j++) visit[i][j]=0; if(n==0&&m==0&&t==0)break; for(i=0;i<n;i++) { scanf("%s",map[i]); for(j=0;j<m;j++) { if(map[i][j]=='S'){bx=i;by=j;} //找到入口位置 if(map[i][j]=='D'){ex=i;ey=j;} //找到出口的位置 if(map[i][j]=='.'){ji++;} //记录可行路的个数 } } if(ji<t){printf("NO\n");continue;} //可行路的个数小于时间 不行 int dis=abs(bx-ex)+abs(by-ey); if((dis+t)%2!=0){printf("NO\n");continue;} //奇偶剪枝 flag=0; visit[bx][by]=1; dfs(bx,by,0); if(flag==1)printf("YES\n"); //正确找到结果 else printf("NO\n"); //为找到结果 } }
下附自己的测试样例
4 4 5
S.X.
..X.
..XD
....
NO
3 4 5
S.X.
..X.
...D
YES
3 4 10
S...
..X.
..D.
YES
3 4 6
....
..X.
.SXD
YES
对四的解释
样例
post code:
#include<stdio.h> #include<stdlib.h> void fun(int t) { printf("t=%d\n",t); int i,nt; if(t==2)return; for(i=1;i<=3;i++) { int nt=t+1; fun(nt); } } int main() { fun(0); system("pause"); }如果我想要的结果是这个:
#include<stdio.h> #include<stdlib.h> void fun(int t) { printf("t=%d\n",t); int i; if(t==2)return; for(i=1;i<=3;i++) { fun(t++); //这里会逐渐改变t的值,因为他包含两步份 加一和赋值不会得到上面想要的结果 //若改成t+1和上面的结果一样 } } int main() { fun(0); system("pause"); }
相关文章推荐
- ZOJ 2110 ( HDU 1010 ) Tempter of the Bone( 比较经典的DFS) --from lanshui_Yang
- Hdu 1010 Tempter of the Bone (DFS 经典奇偶剪枝)
- HDU 1010 Tempter of the Bone【DFS经典题+奇偶剪枝详解】
- HDU 1010 Tempter of the Bone(dfs + 奇偶性剪枝)
- HDU-1010-Tempter of the Bone( DFS + 深度优先搜索 )
- hdu 1010 Tempter of the Bone(DFS+奇偶剪枝)
- (step4.3.1) hdu 1010(Tempter of the Bone——DFS)
- HDU 1010 Tempter of the Bone(DFS)
- HDU 1010 Tempter of the Bone(DFS + 剪枝)
- hdu 1010 Tempter of the Bone(dfs)
- HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
- HDU 1010 Tempter of the Bone(搜索经典题)
- hdu 1010 Tempter of the Bone(dfs+奇偶剪枝)
- HDU 1010 Tempter of the Bone(DFS)
- HDU 1010 Tempter of the Bone (DFS)
- hdu 1010 Tempter of the Bone dfs搜索 奇偶剪枝 解题报告
- hdu1010 Tempter of the Bone (DFS)
- HDU 1010 Tempter of the Bone【经典DPS】
- HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
- hdu-1010 Tempter of the Bone(DFS+奇偶剪枝)