題幹很長這裏就不復制了,題意的話估計看圖就能懂個差不多,這裏簡單說一下,一個球在2爲起點的位置要到達終點3,途中不碰到牆壁球的移動是不會停止的,並且在觸碰牆壁停止後,被碰的牆壁會消失。最後得出到達3需要的最少步數。
思路:還是平常的DFS,不過需要多加一點東西就是了,比如點的移動時用一個循環使其向一個方向一直移動到碰到牆或走出邊界。該題不需要vis標記數組,因爲存在重複走點的情況。注意DFS中加入 if(step>10||step>=ans) return; 可以大大優化時間。(不加一定會TLE)
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
int n,m,flag,ans;
int sx,sy;
int Map[50][50];
int vis[50][50];
void DFS(int x,int y,int w,int step)
{
if(step>10||step>=ans) return;
if(Map[x][y]==0||Map[x][y]==3||Map[x][y]==2)
{
while(1)
{
if(Map[x][y]==2)
{Map[x][y]=0;break;}
if(Map[x][y]==1)
{
Map[x][y]=0;
if(w==1) x++;
else if(w==2) y--;
else if(w==3) x--;
else if(w==4) y++;
break;
}
if(Map[x][y]==-1) return ;
if(Map[x][y]==3)
{
flag=1;
if(ans>step) ans=step;
return ;
}
if(w==1) x--;
else if(w==2) y++;
else if(w==3) x++;
else if(w==4) y--;
}
}
if(Map[x-1][y]!=1&&Map[x-1][y]!=-1)
DFS(x-1,y,1,step+1);
if(Map[x][y+1]!=1&&Map[x][y+1]!=-1)
DFS(x,y+1,2,step+1);
if(Map[x+1][y]!=1&&Map[x+1][y]!=-1)
DFS(x+1,y,3,step+1);
if(Map[x][y-1]!=1&&Map[x][y-1]!=-1)
DFS(x,y-1,4,step+1);
if(w==1) Map[x-1][y]=1;
else if(w==2) Map[x][y+1]=1;
else if(w==3) Map[x+1][y]=1;
else if(w==4) Map[x][y-1]=1;
step--;
}
int main()
{
int i,j;
while(scanf("%d%d",&m,&n),m||n)
{
ans=INF;
flag=0;
memset(Map,-1,sizeof(Map));
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
{
scanf("%d",&Map[i][j]);
if(Map[i][j]==2) sx=i,sy=j;
}
}
DFS(sx,sy,0,0);
if(flag)
{
if(ans<=10)
printf("%d\n",ans);
else
printf("-1\n");
}
else
printf("-1\n");
}
}