时间限制:1000毫秒 | 内存限制:65536 k | |
总提交:22405年 | 接受:9091年 |
描述
行星MM-21,今年奥运会后,冰壶越来越受欢迎。 但规则是与我们的有些不同。 这个游戏在一个冰正方形网格标记的棋盘游戏。 他们只使用一个石头。 游戏的目的是让石头从一开始的目标移动的最小数量。
图1显示了一个示例的一个游戏。 一些方块可能忙于块。 有两个特殊的广场即启动和目标,不忙于块。 (这两个方块是不同的)。 一旦石头开始移动,它将继续进行,直到达到一个街区。 为了把石头目标,您可能必须停止对一块石头打它,再扔。
图1:董事会的例子(开始,G:目标)
石头的运动遵循以下规则:
- 在一开始,石头仍然站在广场。
- 石头的运动限制在x和y方向。 禁止对角线移动。
- 当石头静止时,你可以让它移动,把。 你可能把它立即任何方向,除非它被阻塞(无花果。 2(a))。
- 一旦抛出,石头让搬到同一个方向,直到发生下列之一:
- 石头击中一块(图2(b),(c))。
- 石头停在旁边的广场阻止它。
- 块就消失了。
- 石头的董事会。
- 比赛以失败告终。
- 石头广场到达目标。
- 石头停止成功,游戏结束。
- 石头击中一块(图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; }