poj_3009_Curling 2.0(搜索)

来源:互联网 发布:百度卫士软件怎么样 编辑:程序博客网 时间:2024/05/29 03:01

题型:搜索

题意

外星球上的冰壶运动(太扯了)。。。


冰壶在一个图中滑动,从s点出发,每次推出去都会一直滑下去除非被砖块(block)挡住,停下来之后再继续推。

规则如下:

1、只能在行和列的方向上移动,不能在对角线方向上移动,除了旁边有砖块之外的方向都能移动;

2、冰壶击中砖块的时候:

(1)冰壶停在砖块之前的那一个地方;

  (2)被碰撞过的砖块消失;

3、若是冰壶划出了图之外,则游戏失败;

4、若冰壶到达goal(即G点),冰壶停下来,游戏胜利;

5、若步数不在10次以内,则游戏失败。

求所需的最小步数。

0代表空地;

1代表砖块;

2代表起点;

3代表终点。

如下图:


样例所需最小步数几位5.

分析

此题可以用DFS解决。

问题来了,我们到底怎么来找这些路线呢?

首先我们可以用把S的位置记录下来

然后我们构造一个dfs函数,参数有x , y , step,即当前的点的坐标和步数。

如何来保证能走的方向都走过呢?我们可以用一个二维数组存一下四个方向,然后穷举这些方向就可以了。

接下来就可以通过递归来找出答案了。

代码

#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int inf=999999;int w,h,ans;int map[200][200];int start[2];int dir[4][2]= {{0,-1},{1,0},{0,1},{-1,0}};void dfs(int x,int y,int step){    int xx,yy;    if(step>10) return;    for(int i=0; i<4; i++)    {        if(map[x+dir[i][0]][y+dir[i][1]]!=1)        {            xx=x;            yy=y;            while(map[xx+dir[i][0]][yy+dir[i][1]]!=1)            {                xx=xx+dir[i][0];                yy=yy+dir[i][1];                if(xx<0 || xx>=h || yy<0 || yy>=w)                {                    break;                }                if(map[xx][yy]==3)                {                    if(ans>step)                    {                        ans=step;                    }                    return;                }            }            if(xx>=0 && xx<h && yy>=0 && yy<w)            {                map[xx+dir[i][0]][yy+dir[i][1]]=0;                dfs(xx,yy,step+1);                map[xx+dir[i][0]][yy+dir[i][1]]=1;            }        }    }}int main(){    while(scanf("%d%d",&w,&h)&&w&&h)    {        memset(map,0,sizeof(map));        for(int i=0; i<h; i++)        {            for(int j=0; j<w; j++)            {                scanf("%d",&map[i][j]);                if(map[i][j]==2)                {                    start[0]=i;                    start[1]=j;                }            }        }        ans=inf;        dfs(start[0],start[1],1);        if(ans==inf)        {            printf("-1\n");        }        else        {            printf("%d\n",ans);        }        //cout<<endl;    }    return 0;}