题型:搜索
题意:
外星球上的冰壶运动(太扯了)。。。
冰壶在一个图中滑动,从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;
}