HDU1010(Tempter of the Bone)深搜

原创 2012年03月24日 16:47:14
HDU1010 Tempter of the Bone
广搜每走
思路:简单的深搜,如果map[nextx][nexty]!='X',则以该最后点为当前节点继续搜,若继续搜没有路可走,则释放当前节点(即原来标记过,恢复为未标记,以便再以其他节点搜索时经过该点),回到上一节点,return.由于step是局部变量,其生命周期随着当前层的DFS()函数结束而结束,所以返回上一层时,step的值就是上一层的值,而不是下一层改变后的值,而visit数组因为是全局变量,因此其生命周期只有main函数结束后才结束,因此下一层对visit数组值的改变,在DFS()返回上一层时有影响,值不在是上一层的了,而是改变后的值。
刚开时不明白,逐句调试后才对深搜有了新的认识。
下面的代码,WA了好几次,就是因为把
visit[sx][sy]=1;
if(N*M-wall<=T) {printf("NO\n");continue;}
DFS(sx,sy,0);
写成
if(N*M-wall<=T) {flag=0;}
else{
DFS(sx,sy,0);visit[sx][sy]=1;}
会超时,现在也不知到为什么,可能是杭电OJ有问题吧;
#include<stdio.h>
#include<string.h>
#include<math.h>
int visit[10][10];
int dir[4][2]={-1,0,1,0,0,1,0,-1};
char map[10][10];
int T,N,M;
int flag;
int dx,dy;
void DFS(int sx,int sy,int step)
{
int i,nextx,nexty;
        //下面两行是每次调用DFS(),进入下一层节点时,对其进行检查;
if(map[sx][sy]=='D'&&step==T) {flag=1;return;}   //如果已经搜到‘D',并满足条件就返回上一层节点
if((map[sx][sy]=='D'&&step<T)||step>T)return;    //如果。。。。。。,但是不满足条件则也返回上一层(由上一层的位置搜索其他路径);
for(i=0;i<4;i++)
{

nextx=sx+dir[i][0];
nexty=sy+dir[i][1];
//如果当前节点,某个方向上的下一个节点不越界,并且没有走过
if(nextx<=M&&nextx>=1&&nexty<=N&&nexty>=1&&visit[nextx][nexty]==0)
{    
//如果该方向上的节点可以走,标记该节点,并搜索该节点的下一个方向上的节点;
if(map[nextx][nexty]!='X')        
{visit[nextx][nexty]=1;
DFS(nextx,nexty,step+1);
if(flag) return;     //下一层返回该层时,如果已找到满足条件的路径,则不用再搜该节点其他方向上的节点路径,直接返回该节点的上一层(优化时间);
visit[nextx][nexty]=0;//释放已搜索过当前节点的下一层节点;
}
}
}
}
   
int main()
{
int i,j,wall,sx,sy;
while(scanf("%d%d%d",&M,&N,&T),(N+M+T)!=0)
{
memset(visit,0,sizeof(visit));
flag=0;wall=0;
   getchar();
for(i=1;i<=M;i++)
{ 


for(j=1;j<=N;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='S')
{
sx=i;sy=j;
}

if(map[i][j]=='X')
wall++;
}
          getchar();
} 
    visit[sx][sy]=1;
if(N*M-wall<=T) {printf("NO\n");continue;}//如果能走的点小于T步,则直接输出(优化时间效率);取等号的原因:如果T=6,最多能走的有6个点,其最多能走5步;
      DFS(sx,sy,0);


if(flag)printf("YES\n");
else printf("NO\n");
}
return 0;
}


刚开始使用的广搜,最后别人说不能用广搜,最后才知道原因:
下面是广搜代码:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
char map[10][10];
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int visit[10][10];
int n;
int m;
int T;
struct node
{
    int x;
    int y;
    int step;
};
int BFS(int sx,int sy)
{
    queue<node>Q;
    node cur,next;
    int i,flag=0,sum;
    cur.x=sx;cur.y=sy;
    visit[cur.x][cur.y]=1;
    cur.step =0;
    Q.push(cur);
    while(!Q.empty ())
    {
        cur=Q.front();
            Q.pop ();
        for(i=0;i<4;i++)
        {
            next.x=cur.x+dir[i][0];
            next.y=cur.y+dir[i][1];
            next.step=cur.step+1;
            sum=next.step;
            if(next.x>=1&&next.x<=n&&next.y>=1&&next.y<=m&&visit[next.x][next.y]==0)
            {
                if(map[next.x][next.y]=='.')
                {
                    Q.push(next);
                    visit[next.x][next.y]=1;
                }
                if(sum>T)return 0;
                else if(map[next.x][next.y]=='D'&&sum==T)
                    {
                        flag=1;return 1;
                    }
                else if(map[next.x][next.y]=='D'&&sum<T)
                    return 0;      
            }
            
        }
    }
    if(flag==0) return 0;
}
int main()
{
    int i,j,sx,sy,sun;
    while(scanf("%d%d%d",&n,&m,&T)!=EOF)
    {   
        if(n+m+T==0)break;
        memset(visit,0,sizeof(visit));
        memset(map,0,sizeof(map));  
        for(i=1;i<=n;i++)
        {
            getchar();
            for(j=1;j<=m;j++)
            {
              scanf("%c",&map[i][j]);
              if(map[i][j]=='S')
              {sx=i;sy=j;}
            }
        }
        sun=BFS(sx,sy);
        if(sun==0)printf("No\n");
        else printf("YES\n");
    }
    return 0;
}


如测试实例:
S.X.
.XD.
...X
...X
T=4;
可能路径是:'S'->(2,1)->(3,1)->(4,1)->(4,2)->(4,3)->(3,3)->'D'一共7七步,
还可能的路径是'S'->(2,1)->(3,1)->(3,2)->(3,3)->'D' 共4步;
如果先通过第一种到达了'D',由于(3,3)已被标记走过,所以会找不到符合条件的路径,不像深搜那样找不到,释放路径,可以返回去重找。



hdu 1010 Tempter of the Bone(深搜)

http://acm.hdu.edu.cn/showproblem.php?pid=1010 这个题真是让我蛋疼,原来没有好好看题目,用BFS求了最短路径。好吧我承认我湿了。 用DFS的关键是...

hdu 1010 Tempter of the Bone 深搜+剪枝

Tempter of the Bone Time Limit: 2000/1...

HDU OJ 1010 Tempter of the Bone【深搜】

原题连接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 思路:dfs 深度优先搜索+剪枝 ; 1:因为是某个时刻正好到达door,所以要搜出所有的能...

HDU - 1010 Tempter of the Bone 深搜模板题(DFS)解题报告

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe...
  • Luwhere
  • Luwhere
  • 2015年07月29日 22:26
  • 477

HDU 1010 Tempter of the Bone 经典深搜~DFS

杭电1010题经典的深搜问题 值得一看~~ 解释 一.奇偶剪枝 例如 4*4的矩阵 1 0 1 0 0 1 0 1 1 0 10 0 1 0 1 由1到1 由0到0必走偶数步 由1到...

zoj 2110(hdu 1010)Tempter of the Bone(深搜)

一道很陈的搜索题了,深搜实现的,但我还是发现了一些之前没有注意的地方……第一,全局变量的赋值应该注意,要在函数外部赋初值。第二,就是搜索的优化剪枝问题,这种题很容易超时。下面是代码:#include#...

HDU 1010 Tempter of the Bone 深搜剪枝

Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However...
  • AXuan_K
  • AXuan_K
  • 2014年08月04日 20:18
  • 610

HD1010_Tempter of the Bone(深搜+剪枝)

HD1010_Tempter of the Bone(深搜+剪枝) The doggie found a bone in an ancient maze, which fascinated him a...

HDUOJ-1010 Tempter of the Bone(深搜+剪枝优化)

一开始没仔细看题(英文渣),一扫样例,这不广搜嘛,然后血崩。 认真翻译了一遍。然后用深搜写,然后在一个小错误上面卡了4个小时。。 终于AC了。。 其实个人感觉用广搜也不是不可以,只是超时。。思路...

HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)

Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:HDU1010(Tempter of the Bone)深搜
举报原因:
原因补充:

(最多只允许输入30个字)