一、题意:给定一个矩形区域,代表冰球场。每个单元格可有四种数值:2是冰球的起始位置;3代表冰球最后需要到达的位置;0代表空,球可通过;1代表障碍物,球碰撞一次后,1变成0,球停在1前面那个位置。球只能上下左右移动(一次朝一个方向移动直至碰到1或者3或者出界为止)。求球从2到3的最短步数(必须小于等于10才算),没有则输出-1;
二、思路:遍历球可走的所有情况,找出最短路径。这里需要注意的是步数的回溯。
三、代码:
#include"iostream"
#include"stdio.h"
#include"istream"
using namespace std;
const int MAXN=25;
int filed[MAXN][MAXN];
int column,row,sx,sy,ex,ey,steps,miniSteps;
bool IsEdge(int x,int y)
{
if(x>=0&&x<row&&y>=0&&y<column)
return true;
return false;
}
bool IsEnd(int x,int y)
{
if(x==ex&&y==ey)
return true;
return false;
}
void Dfs(int x,int y)
{
if(steps>10) return;
int dir[8]={0,1,0,-1,1,0,-1,0};
for(int i=0;i<8;i+=2)
{
int dx=x+dir[i];
int dy=y+dir[i+1];
if(IsEdge(dx,dy))
{
if(IsEnd(dx,dy))
{
steps++;
if(miniSteps>steps)
miniSteps=steps;
steps--;
return;
}
else if(filed[dx][dy]==0)
{
while(IsEdge(dx,dy)&&filed[dx][dy]==0)
{
dx+=dir[i];
dy+=dir[i+1];
}
if(IsEdge(dx,dy))
{
if(IsEnd(dx,dy))
{
steps++;
if(miniSteps>steps)
miniSteps=steps;
steps--;
return;
}
steps++;
filed[dx][dy]=0;
Dfs(dx-dir[i],dy-dir[i+1]);
// cout<<dx-dir[i]<<' '<<dy-dir[i+1]<<endl;
filed[dx][dy]=1;
steps--;
}
}
}
}
return;
}
int main()
{
// freopen("in.txt","r",stdin);
while(cin>>column>>row,column&&row)
{
for(int i=0;i<row;i++)
{
for(int j=0;j<column;j++)
{
cin>>filed[i][j];
if(filed[i][j]==2)
{
sx=i;sy=j;
}
if(filed[i][j]==3)
{
ex=i;ey=j;
}
}
}
steps=0;
miniSteps=11;
filed[sx][sy]=0;
Dfs(sx,sy);
if(miniSteps<=10)
cout<<miniSteps<<endl;
else
cout<<-1<<endl;
}
return 0;
}