您的位置:首页 > 其它

HDU 1010第一道剪枝的DFS

2012-05-27 00:54 330 查看
自己写果断超时了,看了大神的剪枝,果然好强悍,附上剪枝

题目大意:这道题就是讲有一只狗要吃骨头,结果进入了一个迷宫陷阱,迷宫里每走过一个地板费时一秒,该地板就会在下一秒塌陷,所以你不能在该地板上逗留。迷宫里面有一个门,只能在特定的某一秒才能打开,让狗逃出去。现在题目告诉你迷宫的大小和门打开的时间,问你狗可不可以逃出去,可以就输出YES,否则NO。

解题思路:这道题,要用到剪枝搜索来做,否则会超时。剪掉的条件是,如果可走地板数目小于给定的时间,绝对不可能得救。还有就是狗走到门的时间必须和题目给定的时间是同奇同偶的,否则也不能在指定的那秒到达门,也不可能得救,剪掉这两种情况后。就用深度搜索来做。从起点出发,深搜周围的路,走过的路就标记为不可走,一直搜索下去,如果搜索失败就回溯,恢复原数据,把可能的路都搜索一遍过去,看看是否有可行方案。

关于剪枝,没有剪枝的搜索不太可能,一个是奇偶剪枝,一个是路径剪枝

奇偶剪枝:

把矩阵标记成如下形式:

0,1,0,1,0

1,0,1,0,1

0,1,0,1,0

1,0,1,0,1

很明显,如果起点在0 而终点在1 那显然 要经过奇数步才能从起点走到终点,依次类推,奇偶相同的偶数步,奇偶不同的奇数步

在读入数据的时候就可以判断,并且做剪枝,当然做的时候并不要求把整个矩阵0,1刷一遍,读入的时候起点记为(Si,Sj) 终点记为(Di,Dj) 判断(Si+Sj) 和 (Di+Dj) 的奇偶性就可以了

路径剪枝:

矩阵的大小是N*M 墙的数量记为num 如果能走的路的数量 N*M - num 小于时间T,就是说走完也不能到总的时间的,这显然是错误的,可以直接跳出了

剪枝3:就是记录当前点到终点的最短路,如果小于剩余的时间的话,就跳出

#include<stdio.h>
#include<math.h>
#include<string.h>
typedef struct
{
int x;
int y;
}position;
position exit,move[4]={-1,0,0,1,1,0,0,-1};
char maze[10][10];
int visited[10][10],t,sum;
bool found;
void dfs(position,int );
void wall(int r,int c);
void findenter(position &,position&,int ,int );
int main()
{
position enter;
int r,c,i;
while(scanf("%d %d %d",&r,&c,&t)&&r+c+t)
{
sum=0;
found=false;
memset(visited,0,sizeof(visited));
for(i=1;i<=r;i++)
scanf("%s",&maze[i][1]);
wall(r,c);
findenter(enter,exit,r,c);
if(sum+1<t)
{
printf("NO\n");
continue;
}
dfs(enter,0);
if(found) printf("YES\n");
else printf("NO\n");
}
return 0;
}
void wall(int r,int c)
{
int i;
for(i=0;i<=r+1;i++)
{
maze[i][0]='X';
maze[i][c+1]='X';
}
for(i=0;i<=c+1;i++)
{
maze[0][i]='X';
maze[r+1][i]='X';
}
}
void findenter(position &enter,position &exit,int r,int c)
{
int i,j;
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
{
if(maze[i][j]=='.')
sum++;
else if(maze[i][j]=='S')
{
enter.x=i;
enter.y=j;
}
else if(maze[i][j]=='D')
{
exit.x=i;
exit.y=j;
}
}
}
void dfs(position now,int step)
{
int i,temp;
position next;
if(found) return ;
if(maze[now.x][now.y]=='D'&&step==t)
{
found=true;
return;
}
temp=t-step-abs(now.x-exit.x)-abs(now.y-exit.y);
if(temp<0||temp%2) return ;
visited[now.x][now.y]=1;
for(i=0;i<4;i++)
{
next.x=now.x+move[i].x;
next.y=now.y+move[i].y;
if(!visited[next.x][next.y]&&maze[next.x][next.y]!='X')
{
visited[next.x][next.y]=1;
dfs(next,step+1);
visited[next.x][next.y]=0;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: