poj3009

来源:互联网 发布:大尺度网络电影 编辑:程序博客网 时间:2024/04/27 14:45
#include <iostream>
#include <stdio.h>
#include <cstring>


using namespace std;


int w,h,sx,sy,ex,ey,maze[25][25],ans,
    dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};


void dfs(int x,int y,int step)    //step作为参数
{
    if (step>10||step>ans) return;  //结束条件
    for (int i=0;i<4;i++)   //穷举所有可能
    {
        int xx=x,yy=y;
        while (1)
        {
            xx+=dx[i];yy+=dy[i];                        //一步一步走
            if (xx<1||xx>h||yy<1||y>w) break;          //越界不符合条件,换一个方向
            if (xx==ex&&yy==ey)                         //到终点
            {
                step++;
                if (step<ans) ans=step;               //记录最小值
                return;                                     //回到上一层dfs
            }
            else if (maze[xx][yy]==1)                //遇到障碍
            {
                if (xx-dx[i]!=x||yy-dy[i]!=y)           //若xx-dx[i]==x&&yy-dy[i]==y,说明从静止时开始走的第一步就遇到障碍,
                                                        //此时该方向不能走,障碍也不会消失,障碍只有在方块运动时撞击才会消失
                {
                    maze[xx][yy]=0;                         //消去方块
                    dfs(xx-dx[i],yy-dy[i],step+1);            //dfs
                    maze[xx][yy]=1;                             //还原方块
                }
                break;                                   //遇到障碍则该方向结束
            }
        }


    }
}


/*void dfs(int x,int y)                        //step作为全局变量,初始化为0
{
    if (step>=10) return;
    for (int i=0;i<4;i++)
    {
        int xx=x,yy=y;
        while (1)
        {
            xx+=dx[i];yy+=dy[i];
            if (xx<1||xx>h||yy<1||y>w) break;
            if (xx==ex&&yy==ey)
            {
                step++;
                if (step<ans) ans=step;
                step--;                              //还原step,再回到上一层dfs
                return;
            }
            else if (maze[xx][yy]==1)
            {
                if (xx-dx[i]!=x||yy-dy[i]!=y)
                {
                    maze[xx][yy]=0;
                    step++;
                    dfs(xx-dx[i],yy-dy[i]);
                    step--;                            //还原step,
                    maze[xx][yy]=1;
                }
                break;
            }
        }


    }
}
*/


int main()
{
    freopen("in.txt","r",stdin);
    cin>>w>>h;
    while (w+h!=0)
    {
     memset(maze,0,sizeof(maze));  //一定要全部初始化!!!!!
     for (int i=1;i<=h;i++)
        for (int j=1;j<=w;j++)
        {
           cin>>maze[i][j];
           if (maze[i][j]==2) {sx=i;sy=j;}
           if (maze[i][j]==3) {ex=i;ey=j;}
        }
    ans=15;
    dfs(sx,sy,0);
    if (ans<=10) cout<<ans<<endl;else cout<<"-1"<<endl;
    cin>>w>>h;
    }
    return 0;
}
/*题意:搜索,已知起点和终点,求石子从起点到达终点的最短路,如果无法到达,则输出-1。石子移动的具体规则如下:
   1、开始时,石子在起点s处
   2、运动方向可以是水平或垂直的,不能斜方向运动
   3、最开始的时候,你可以将石子向上下左右任意一个方向抛,如果与它相邻的点是障碍物的话除外
   4、一旦石子开始运动,有三种可能:
      a、遇到障碍物,石子会停在障碍物的前一格,障碍物会消失
      b、如果出界,游戏失败
      c、到达终点,游戏结束并成功
   5、如果移动的次数超过10次,将认为游戏是失败的
算法:dfs求最短路,因为障碍会消失,bfs无法保存状态*/
0 0
原创粉丝点击