poj3009 Curling 2.0 DFS搜索

On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is played on an ice game board on which a square mesh is marked. They use only a single stone. The purpose of the game is to lead the stone from the start to the goal with the minimum number of moves.

Fig. 1 shows an example of a game board. Some squares may be occupied with blocks. There are two special squares namely the start and the goal, which are not occupied with blocks. (These two squares are distinct.) Once the stone begins to move, it will proceed until it hits a block. In order to bring the stone to the goal, you may have to stop the stone by hitting it against a block, and throw again.

题意:好难看懂。。还是找的翻译。

题目说的是一种冰壶的游戏,起点在2,终点在3,1是墙,0是滑动区域。

就是要求把一个冰壶从起点“2”用最少的步数移动到终点“3”

其中0为移动区域,1为石头区域,冰壶一旦想着某个方向运动就不会停止,也不会改变方向(想想冰壶在冰上滑动),除非冰壶撞到石头1 或者 到达终点 3

要注意的是:

冰壶撞到石头后,冰壶会停在石头前面,此时(静止状态)才允许改变冰壶的运动方向,而该块石头会破裂,石头所在的区域由1变为0. 也就是说,冰壶撞到石头后,并不会取代石头的位置。

终点是一个摩擦力很大的区域,冰壶若到达终点3,就会停止在终点的位置不再移动。

题解:从起点开始搜索第一个0,也就是可以滑动的地方,然后开始用DFS搜索,因为冰壶是遇到墙才会停止,那么就只有两种可能,一种是碰到墙,一种是跑出去了,这种情况要换个方向重新搜索,一直走到碰到墙的时候,就把墙“1”变成“0”,然后在遇到墙的上一个地方DFS搜索。这样就可以找到最少的时间到达3终点。

#include<iostream>
#include<cstring>
using namespace std;
int n,m;
int a[105][105];
int ex,ey,sx,sy,sum;
int f[4][2]={0,1,1,0,0,-1,-1,0};
void dfs(int x,int y,int num)
{
    if(num>10)
        return ;
    int flag;
    for(int i=0;i<4;i++)
    {
        flag=0;
        int nx=x+f[i][0];
        int ny=y+f[i][1];
        if(a[nx][ny]==1)//找到第一个可以滑动的区域。
            continue;
            nx=x;
            ny=y;//要直线运动直到撞墙,所以把x,y赋值。
        while(1)
        {
            nx=nx+f[i][0];
            ny=ny+f[i][1];
            if(nx>0&&ny>0&&nx<=m&&ny<=n)
            {
                if(a[nx][ny]==3)
                {
                    if(sum>num)
                        sum=num;
                    return ;
                }
                else if(a[nx][ny]==1)
                {
                    break;
                }
            }
            else//出界了就继续换个方向搜索。
            {
                flag=1;
                break;
            }
        }
        if(flag)
            continue;
        else
        {
            a[nx][ny]=0;
            dfs(nx-f[i][0],ny-f[i][1],num+1);
            a[nx][ny]=1;
        }
    }
}
int main()
{
    while(cin>>n>>m)
    {
        if(n==0&&m==0)
            break;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
            if(a[i][j]==2)
            {
                ex=i,ey=j;
            }
            if(a[i][j]==3)
                sx=i,sy=j;
        }
        sum=0x3f3f3f;//因为是计算最小的,所以初始设为INF。
        dfs(ex,ey,1);
        if(sum==0x3f3f3f)
            cout<<"-1"<<endl;
        else
            cout<<sum<<endl;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值