http://poj.org/problem?id=3009
题意:给定一个m*n的网格,在这些网格上一些地方有障碍物,给定起点与终点的位置,当石头从起点开始走,撞上障碍才会转弯,否则会一直沿着来时的方向继续前进。撞到障碍后停在障碍前的位置,障碍消失。然后石头可以选择四个方向(相邻处无障碍的方向)前进,问至少需要停多少次才能从起点到达终点。不能到达或者多余10步后游戏失败。如果能到达输出最少的步数,否则输出-1。
思路:DFS,多余10步为剪枝条件。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 int dx[4]={-1,0,1,0}; 8 int dy[4]={0,1,0,-1}; 9 int ex,ey,n,m,ans; 10 int map[22][22]; 11 int check(int x,int y) 12 { 13 if(x<0||x>=m||y<0||y>=n) 14 return 0; 15 return 1; 16 } 17 void dfs(int x,int y,int c) 18 { 19 if(c>10) 20 return; 21 for(int i=0;i<4;i++) 22 { 23 int nx=x+dx[i]; 24 int ny=y+dy[i]; 25 if(map[nx][ny]==1) //在转弯时走不通或起步时走不通 26 continue; 27 while(!map[nx][ny]) //可行的路一直走到不是0的地方为止 28 { 29 nx=nx+dx[i]; 30 ny=ny+dy[i]; 31 } 32 if(check(nx,ny)) //如果没有跑出界外 33 { 34 if(map[nx][ny]==1) 35 { 36 map[nx][ny]=0; //击碎障碍物 37 dfs(nx-dx[i],ny-dy[i],c+1); //后退一步继续搜索 38 map[nx][ny]=1; //回溯要复原原来的场景,关键点 39 } 40 if(map[nx][ny]==3) 41 if(c<ans) 42 ans=c; 43 } 44 } 45 } 46 main() 47 { 48 int i,j,x,y; 49 while(~scanf("%d%d",&n,&m)&&(n!=0||m!=0)) 50 { 51 for(i=0;i<m;i++) 52 { 53 for(j=0;j<n;j++) 54 { 55 scanf("%d",&map[i][j]); 56 if(map[i][j]==2){ 57 map[i][j]=0; 58 x=i;y=j; 59 } 60 else if(map[i][j]==3) 61 { 62 ex=i;ex=j; 63 } 64 } 65 } 66 ans=99999; 67 dfs(x,y,1); 68 if(ans>10) 69 printf("-1 "); 70 else 71 printf("%d ",ans); 72 } 73 }