http://poj.org/problem?id=3009

题意 : 迷宫升级版,也是m*n的迷宫,0是可以走的,1是阻塞,2是初始点,3是目标位置,这个的阻塞是可以消除的,就是说只要石头撞到阻塞,阻塞就由1变为0了,石头这个时候是可以停下来的,也就是说石头只有撞上阻塞停下来才算走了一步,还有要注意的一点是石头停了下来的时候不是停在阻塞那个点那的,还是它撞阻塞之前的那个位置,求出走到目标位置需要的步数,若步数超过了10步就输出-1;

思路 : 典型的DFS,递归就行,不过注意一下结束条件就行了

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 1010 ;
int ch[maxn][maxn] ;
int ans,m,n;
int dix[] = {0,0,-1,1} ;//x轴方向上的变化,分别为上下左右
int diy[] = {1,-1,0,0} ;
void dfs(int i,int j,int step)//i,j为初始的坐标,step为走的步数
{
    if(step >= 10||step>=ans)//如果步数超出10或者步数大于最小移动次数
        return ;
    int x,y;
    for(int h = 0 ; h < 4 ; h++)//四个方向进行遍历
    {
        x = i+dix[h] ;
        y = j+diy[h] ;
        if(ch[x][y] == 1)//如果是阻塞,就跳出
            continue ;
        while(1)
        {
            if(x>=0&&x<n&&y >= 0&&y < m)//没有超出边界
            {
                if(ch[x][y] == 1)
                {
                    ch[x][y] = 0 ;//因为撞到阻塞就可以让阻塞消除,并且可以停止
                    dfs(x-dix[h],y-diy[h],step+1);//然后再4个方向进行遍历
                    ch[x][y] = 1 ;//若是没找到就再恢复原样
                    break ;
                }
                if(ch[x][y] == 3)
                {
                    ans = min(ans,step+1);
                    break;
                }
            }
            else if(!(x>=0&&x<n&&y >= 0&&y < m))
                break;
            x += dix[h];//如果未遇到阻塞就一直往前走                                                                                                                                                                                                                                                                                                                                                                                                                
            y += diy[h];
        }
    }
}
int main()
{
    while(cin>>m>>n)
    {
        if(n == 0&&m == 0)
            break ;
        int x,y ;
        ans = 11;//ans为从开始位置到目标位置的最少移动次数,初始化为11
        for(int i = 0 ; i < n ; i++)
        {
            for(int j = 0 ; j < m ; j++)
            {
                cin>>ch[i][j] ;
                if(ch[i][j] == 2)//记录下初始位置的横纵坐标
                {
                    x = i ;
                    y = j ;
                }
            }
        }
        dfs(x,y,0) ;
        if(ans==11) printf("-1\n");
        else printf("%d\n",ans);
    }
    return 0;
}
View Code

 

 

posted on 2013-08-27 20:29  枫、  阅读(197)  评论(0编辑  收藏  举报