Curling 2.0

卷2.0
时间限制:1000毫秒 内存限制:65536 k
总提交:22405年 接受:9091年

描述

行星MM-21,今年奥运会后,冰壶越来越受欢迎。 但规则是与我们的有些不同。 这个游戏在一个冰正方形网格标记的棋盘游戏。 他们只使用一个石头。 游戏的目的是让石头从一开始的目标移动的最小数量。

图1显示了一个示例的一个游戏。 一些方块可能忙于块。 有两个特殊的广场即启动和目标,不忙于块。 (这两个方块是不同的)。 一旦石头开始移动,它将继续进行,直到达到一个街区。 为了把石头目标,您可能必须停止对一块石头打它,再扔。


图1:董事会的例子(开始,G:目标)

石头的运动遵循以下规则:

  • 在一开始,石头仍然站在广场。
  • 石头的运动限制在x和y方向。 禁止对角线移动。
  • 当石头静止时,你可以让它移动,把。 你可能把它立即任何方向,除非它被阻塞(无花果。 2(a))。
  • 一旦抛出,石头让搬到同一个方向,直到发生下列之一:
    • 石头击中一块(图2(b),(c))。
      • 石头停在旁边的广场阻止它。
      • 块就消失了。
    • 石头的董事会。
      • 比赛以失败告终。
    • 石头广场到达目标。
      • 石头停止成功,游戏结束。
  • 你不能扔石头游戏超过10次。 如果石头不达到目标在10个动作,比赛以失败告终。


图2:石头的动作

根据规则,我们想知道石头开始时是否能达到我们的目标,如果是,所需的最小数量的变动。

图1所示的初始配置,4需要把石头从开始的目标。 图3所示的途径是(a)。 注意当石头到达目标,董事会配置改变了如图3(b)。


图3:图d 1和最终的解决方案配置

输入

数据集的输入是一个序列。 输入显示的最后一行包含两个0之间用一个空格来分隔。 数据集的数量不会超过100。

每个数据集格式如下。

宽度(= w)和高度(= h)的董事会 
第一行的董事会
 

h-th行董事会

板的宽度和高度满足:2 < =w< = 20,1 < =h< = 20。

每一行包含w小数分隔的空间。 数量描述的状态对应的广场。

0空方
1
2起始位置
3目标位置

图的数据集d 1如下:

6个6
1 0 0 2 1 0
1 1 0 0 0 0
0 0 0 0 0 3
0 0 0 0 0 0
1 0 0 0 0 1)
0 1 1 1 1 1

输出

对于每个数据集,打印一行有一个十进制整数最小数量的沿着路线从一开始的目标。 如果没有这样的路线,打印1代替。 每一行不应该这个数字以外的任何字符。

样例输入

2 1
3 - 2
6个6
1 0 0 2 1 0
1 1 0 0 0 0
0 0 0 0 0 3
0 0 0 0 0 0
1 0 0 0 0 1)
0 1 1 1 1 1
6个1
1 1 2 1 1 3
6个1
1 0 2 1 1 3
12个1
2 0 1 1 1 1 1 1 1 1 1 3
13 1
2 0 1 1 1 1 1 1 1 1 1 1 3
0 0

样例输出

1
4
1
4
10
1
个人理解:参考百度答案的

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;

#define INF 0x3f3f3f3f
int w,h,minstep;
int sx,sy;
int g[25][25];
int dr[]={0,0,1,-1};
int dc[]={1,-1,0,0};
bool inside(int x,int y)
{
    return x>=0&&x<h&&y>=0&&y<w;
}
void dfs(int x,int y,int step)//step作为参量
{
    if(step>=10)return ;
    for(int i=0;i<4;i++)
    {
        int nx=x+dr[i],ny=y+dc[i];
        if(g[nx][ny]==1)continue;//一定要先判断一下,可能一开始g[nx][ny]=1,这样就根本无法往下走
        while(inside(nx,ny)&&g[nx][ny]!=1&&g[nx][ny]!=3)//沿着0一直走
        {
            nx+=dr[i];ny+=dc[i];
        }
        if(!inside(nx,ny))continue;//如果越界就不用往下进行了
        if(g[nx][ny]==3)
        {
            minstep=min(minstep,step+1);
        }
        else if(g[nx][ny]==1)
        {
            g[nx][ny]=0;
            dfs(nx-dr[i],ny-dc[i],step+1);//一定要减去最后一步,因为碰到障碍后还是从原先的位置走,不是从障碍的位置走
            g[nx][ny]=1;
        }
    }
}
int main()
{
    while(cin>>w>>h&&w+h)
    {
        for(int i=0;i<h;i++)
        {
            for(int j=0;j<w;j++)
            {
                cin>>g[i][j];
                if(g[i][j]==2)sx=i,sy=j;
            }
        }
        minstep=INF;
        dfs(sx,sy,0);
        if(minstep!=INF)cout<<minstep<<endl;
        else cout<<-1<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值