题目:http://poj.org/problem?id=3009
题意:
就是要求把一个冰壶从起点“2”用最少的步数移动到终点“3”
其中0为移动区域,1为石头区域,冰壶会一直向着一个方向走下去,一直撞到石头或者到达终点才能改变方向,撞到石头时会停在石头前面而且这块石头会破碎,到终点会停止
大概的思路就是:一个方向要是能走就就一直走下去一直到不能再往前走,然后就换方向(此时用while就可以解决,不需要递归调用),还有就是注意场地的恢复
View Code
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define pan(a,b,c) (a<=b&&b<=c) 5 #define min(a,b) (a>b? b:a) 6 7 using namespace std; 8 9 int map[25][25]; 10 int sx,sy; 11 int a[4][2]={{0,1},{-1,0},{0,-1},{1,0}}; 12 int res; 13 int n,m; 14 void dfs(int ax,int ay,int step) 15 { 16 if(step>11) 17 return ; 18 int i; 19 int xx,yy; 20 int flag; 21 for(i=0;i<4;i++) 22 { 23 if(pan(1,ax+a[i][0],n)&&pan(1,ay+a[i][1],m)&&map[ax+a[i][0]][ay+a[i][1]]==1) 24 continue; 25 xx=ax; 26 yy=ay; 27 flag=1; 28 while(1) 29 { 30 xx=xx+a[i][0]; 31 yy=yy+a[i][1]; 32 if(!(pan(1,xx,n)&&pan(1,yy,m))) 33 { 34 flag=0; 35 break; 36 } 37 if(map[xx][yy]==1) 38 { 39 break; 40 } 41 if(map[xx][yy]==3) 42 { 43 step++; 44 res=min(res,step); 45 return ; 46 } 47 if(map[xx][yy]==0) 48 continue; 49 } 50 if(!flag) 51 { 52 continue; 53 } 54 map[xx][yy]=0; 55 dfs(xx-a[i][0],yy-a[i][1],step+1); 56 map[xx][yy]=1; 57 } 58 } 59 int main() 60 { 61 int i,j; 62 while(scanf("%d %d",&m,&n)!=EOF) 63 { 64 65 if(m==0&&n==0) 66 break; 67 res=20; 68 memset(map,0,sizeof(map)); 69 for(i=1;i<=n;i++) 70 { 71 for(j=1;j<=m;j++) 72 { 73 scanf("%d",&map[i][j]); 74 { 75 if(map[i][j]==2) 76 { 77 sx=i; 78 sy=j; 79 map[i][j]=0; 80 } 81 } 82 } 83 } 84 dfs(sx,sy,0); 85 if(res<=10) 86 cout<<res<<endl; 87 else 88 cout<<"-1"<<endl; 89 } 90 return 0; 91 }