题目链接:http://poj.org/problem?id=3009
题意:类似冰壶比赛。在一个矩阵中有一个起点一个终点,有空地和障碍物。从起点开始可以使冰壶朝一个方向运动(如果该方向没有障碍物的话)直到撞到障碍或者飞出边界或者到达终点,飞出边界游戏失败,撞到障碍障碍消失,冰壶停在障碍前,可以使得冰壶再次运动,问能不能在十次(包括)操作之内使得冰壶到达终点,不能则输出-1。能则输出最少的操作次数。
题解:DFS。只不过在DFS的时候的状态转移并不是相邻的一个格子,而是上下左右四条直线。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX=25;
int a[MAX][MAX];
int w,h;
int step,minstep;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int sx=0,sy=0;
void dfs(int x,int y,int step)
{
if(step>10) return ;
//cout<<x<<" "<<y<<" "<<step<<endl;
for(int i=0;i<4;i++)
{
for(int j=1;;j++)
{
int nx=x+j*dx[i];
int ny=y+j*dy[i];
if(a[nx][ny]==3)
{
minstep=min(minstep,step);
return ;
}
if(nx<0||nx>=h||ny<0||ny>=w)
{
break;
}
if(a[nx][ny]==1)
{
if(j==1) break;
else
{
a[nx][ny]=0;
dfs(nx-dx[i],ny-dy[i],step+1);
a[nx][ny]=1;
break;
}
}
}
}
return ;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&w,&h))
{
memset(a,0,sizeof(a));
if(w==0&&h==0) break;
step=0;
minstep=12;
for(int i=0;i<h;i++)
{
for(int j=0;j<w;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==2)
{
sx=i;
sy=j;
}
}
}
dfs(sx,sy,1);
if(minstep>10) printf("-1\n");
else printf("%d\n",minstep);
}
return 0;
}