HDU 1010第一道剪枝的DFS

来源:互联网 发布:汽车数据采集驱动系统 编辑:程序博客网 时间:2024/05/22 17:01

自己写果断超时了,看了大神的剪枝,果然好强悍,附上剪枝

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


原创粉丝点击