hud1010题Tempter of the Bone
题目链接;http://acm.hdu.edu.cn/showproblem.php?pid=1010
题目意思就是问t时刻是否可以从S到达D处;其中有w墙的阻碍。
一道剪枝题;先了解一下奇偶剪枝和路径剪枝;
就该题而言;
奇偶剪枝的;(剩余步数(最短的)与剩余的时间同奇偶)
原理;在矩阵中当初末位置确定后,那么它从初到末的步数的奇偶也就确定了。(因为每弯一次都是增加2步,不改变奇偶性的);
初末位置的最短路径(不走对角)
abs(ex-sx)+abs(ey-sy);
动态的最短路径是; abs(ex-x)+abs(ey-y);
再结合剩余的时间;就可以得出;
剩余的时间也要与剩余的最短路径同奇偶才能实现在t时刻到达D处;
team=abs(t-cen)-(abs(ex-x)+abs(ey-y));//剩余的时间也要与剩余的最短路径同奇偶
if(temp%2==1)return;//意思就是这条路径不行,返回上一级;
路径剪枝;
1’;在最开始的时候可以判断‘可以走的格子个数小于时间则不能到达’;
2’;剩余的最短路径要小于剩余的时间;否则不能到达;
team=abs(t-cen)-(abs(ex-x)+abs(ey-y));//剩余的时间减去剩余的最短路径;
if(team<0)return ;//意思就是这条路径不行,返回上一级;
两者结合起来就是;
team=abs(t-cen)-(abs(ex-x)+abs(ey-y));//剩余的时间减去剩余的最短路径;
if(team<0||temp%2==1)return ;//意思就是这条路径不行,返回上一级;
这题目除了剪枝外还有一个小知识;就是回溯;
每次完成一次搜索之后又要把其还原为’.’;
代码;
if(fx>=0&&fx<n&&fy>=0&&fy<m&&map[fx][fy]!='X')
{
map[fx][fy]='X';//变化;这个步骤就是实现搜索的中心
dfs(fx,fy,cnt+1);
map[fx][fy]='.'; //回溯
}
也正是他们两者的转化才实现了,搜索;
题目代码;
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int m,n,t;
char map[8][8];
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
int ex,ey,sx,sy,k;//e表示end,终点,s表示start,出发点,ok用来判断是否在规定时间到达
void dfs(int x,int y,int cnt)
{
int i;
if(cnt==t)//剪枝1:到时间了符合条件ok=1再退出,不符合条件直接退出。
{
if(ex==x&&ey==y)k=1;
return;
}
if(k) return;//找到解后还有部分在继续搜索,这条是为了让其它搜索停止;
//动态判断,路径与时间的奇偶性;
int temp=abs(cnt-t)-(abs(x-ex)+abs(y-ey));//剪枝2:((((要点))))
//奇偶性剪枝 ,起点和终点确定以后就可以确定走的步数是奇数还是偶数,通过这个特点来剪枝
if(temp<0||temp%2==1)return;
for(i=0;i<4;i++)
{
int fx=x+dir[i][0];
int fy=y+dir[i][1];
if(fx>=0&&fx<n&&fy>=0&&fy<m&&map[fx][fy]!='X')
{
map[fx][fy]='X';//变化;这个步骤就是实现搜索的中心
dfs(fx,fy,cnt+1);
map[fx][fy]='.'; //回溯
}
}
return ;
}
int main()
{
int i,j,wall;
while(scanf("%d %d %d",&n, &m, &t) != EOF){
wall=0;
if(n==0&&m==0&&t==0)
break;
for(i = 0; i < n; i++){
scanf("%s",map[i]);
for(j=0;map[i][j]!='\0';j++){
if(map[i][j]=='S'){
sx=i;sy=j;
}
else if(map[i][j]=='D'){
ex=i;ey=j;
}
else if(map[i][j]=='X')
wall++;
}
}
if(m*n-wall<=t) printf("NO\n");//剪枝3:能走的格子个数比时间少的话,直接不符合,不用再搜了
else
{
k=0;
map[sx][sy]='X';
dfs(sx,sy,0);
if(k)printf("YES\n");
else printf("NO\n");
}
}
return 0 ;
}