(1)类型:深搜。
(2)题意:给你一个w*h的冰球场,0代表障碍,1代表有障碍,2代表起始位置,3代表终止位置。当球员从初始位置出发选择无障碍(0)的方向移动,一直到遇到障碍(1)停止,此时障碍(1)变为无障碍(0)。问球员从初始位置一直到终止位置最少移动(注意是移动的次数不是移动的方格数)的次数。
(3)解题思路:记录每一次到达一个障碍移动的最少次数,每次计算时进行更新即可。
(4)时间复杂度:O(n*n)。
(5)总结:&由于题目要求为移动的次数而非移动的方格数,所以一开始的思路较为混乱,后来选择用一种特殊方法处理可以简便很多(具体看dfs()函数中的内容)。
&其次就是最少需要次数的更新,就是利用min函数更新每次计算到的移动次数的最小值。
(6)代码:
#include<iostream>
#include<cstring>
const int MAX_N=20+1;
using namespace std;
int map[MAX_N][MAX_N],step,res,w,h;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
void dfs(int step,int x,int y){
if(map[x][y]==3)res=min(res,step);
else {
if(step<10)
for(int i=0;i<4;i++)
for(int j=1;;j++)
if(x+j*dx[i]>=0&&x+j*dx[i]<h&&y+j*dy[i]>=0&&y+j*dy[i]<w&&map[x+dx[i]][y+dy[i]]!=1){
if(map[x+j*dx[i]][y+j*dy[i]]==1){
map[x+j*dx[i]][y+j*dy[i]]=0;
dfs(step+1,x+(j-1)*dx[i],y+(j-1)*dy[i]);
map[x+j*dx[i]][y+j*dy[i]]=1;
break;
}
else if(map[x+j*dx[i]][y+j*dy[i]]==3){
dfs(step+1,x+j*dx[i],y+j*dy[i]);
break;
}
}
else break;
}
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
while(cin>>w>>h,h||w){
res=0x3f3f3f3f;
memset(map,-1,sizeof(map));
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)cin>>map[i][j];
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
if(map[i][j]==2)dfs(0,i,j);
if(res<=10)cout<<res<<endl;
else cout<<-1<<endl;
}
}