Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
这道题大意是一个在一个w*h的场地放一个冰壶(数字2),冰壶每次可以向一个方向滑,撞到冰(数字1)才能停下,且此时此冰破碎变成空地(数字0)。输出冰壶经过终点(数字3)最少要多少次(无法在10次内完成输出-1)。注意冰壶滑出界直接失败。
虽说是求最短次数但由于地图一直在变,还是用dfs比较好(由于最多允许滑10次所以不会超时),另外方向与行列也是经常弄混。。。反正这题建议和我一样练习dfs的新人可以做一做。
本人代码思路是提前预判停下的时机,在停下后判断前面遇到的是1,是3,亦或是地图边界,代码如下:
这道题大意是一个在一个w*h的场地放一个冰壶(数字2),冰壶每次可以向一个方向滑,撞到冰(数字1)才能停下,且此时此冰破碎变成空地(数字0)。输出冰壶经过终点(数字3)最少要多少次(无法在10次内完成输出-1)。注意冰壶滑出界直接失败。
虽说是求最短次数但由于地图一直在变,还是用dfs比较好(由于最多允许滑10次所以不会超时),另外方向与行列也是经常弄混。。。反正这题建议和我一样练习dfs的新人可以做一做。
本人代码思路是提前预判停下的时机,在停下后判断前面遇到的是1,是3,亦或是地图边界,代码如下:
#include <iostream>
using namespace std;
#define N 10
int Map[22][22],Min;
int m,n; ///m横n竖
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int in(int x,int y){
return x>=0&&y>=0&&x<m&&y<n;
}
void dfs(int x,int y,int cnt){
if(cnt>=Min||cnt>N)return;
int cx,cy,tx,ty;
for(int i=0;i<4;i++){
cx=dir[i][1]; ///选择一个方向
cy=dir[i][0];
tx=x;
ty=y;
if(!in(tx+cx,ty+cy)||Map[ty+cy][tx+cx]==1) ///无法移动
continue;
while(in(tx+cx,ty+cy)&&Map[ty+cy][tx+cx]==0){ ///移动
tx+=cx;
ty+=cy;
}
if(in(tx+cx,ty+cy)&&Map[ty+cy][tx+cx]==3){ ///找到了终点
Min=cnt;
return;
}
if(in(tx+cx,ty+cy)&&Map[ty+cy][tx+cx]==1){ ///碰到了墙壁
Map[ty+cy][tx+cx]=0;
dfs(tx,ty,cnt+1);
Map[ty+cy][tx+cx]=1;
}
else ; ///碰到了地图边界
}
}
int main(){
int i,j,x,y;
while(cin>>m>>n&&m+n){
Min=11;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
cin>>Map[i][j];
if(Map[i][j]==2)Map[y=i][x=j]=0;
}
}
dfs(x,y,1);
if(Min==11)cout<<-1<<endl;
else cout<<Min<<endl;
}
}