http://poj.org/problem?id=3009
题意:溜石游戏。在一给定大小的矩形冰面上,散布若干石块,给定石头的初始位置和终点,求从起点到达终点的最小步数,超过10次则视作不可达。其中规则如下,若石头与石块有相邻则不能向该方向滑动;每次溜石只能到达有石块的地方,且将其立即敲碎;若出界则视作失败。 思路:限制条件较多的dfs,每个状态下有四个方向的选择,注意每个滑动方向中的情况,较繁琐。 #include<stdio.h> #include<iostream> const int inf=999999; using namespace std; int r,c,step,sx,sy,ex,ey; int inmap(int x,int y) { if(x>=1&&x<=r&&y>=1&&y<=c)return 1; else return 0; } void dfs(int x,int y,int num,int map[][30]) { int i,j,k; if(num>10)return;//注意这的终止条件,我就tle 一次 i=x; j=y; k=num; while(map[i][j+1]==0&&inmap(i,j+1))//向右 { j++; } if(inmap(i,j+1)&&map[x][y+1]!=1) { k++; if(i==ex&&j+1==ey) { step=min(step,k); return ; } map[i][j+1]=0; dfs(i,j,k,map); map[i][j+1]=1; } i=x; j=y; k=num; while(map[i+1][j]==0&&inmap(i+1,j))//向下 { i++; } if(inmap(i+1,j)&&map[x+1][y]!=1) { k++; if(i+1==ex&&j==ey) { step=min(step,k); return ; } map[i+1][j]=0; dfs(i,j,k,map); map[i+1][j]=1; } i=x; j=y; k=num; while(map[i][j-1]==0&&inmap(i,j-1))//向左 { j--; } if(inmap(i,j-1)&&map[x][y-1]!=1) { k++; if(i==ex&&j-1==ey) { step=min(step,k); return ; } map[i][j-1]=0; dfs(i,j,k,map); map[i][j-1]=1; } i=x; j=y; k=num; while(map[i-1][j]==0&&inmap(i-1,j))//向上 { i--; } if(inmap(i-1,j)&&map[x-1][y]!=1) { k++; if(i-1==ex&&j==ey) { step=min(step,k); return ; } map[i-1][j]=0; dfs(i,j,k,map); map[i-1][j]=1; } } int main() { int map[30][30],i,j; while(scanf("%d%d",&c,&r),r+c) { for(i=1;i<=r;i++) { for(j=1;j<=c;j++) { scanf("%d",&map[i][j]); if(map[i][j]==2) { sx=i; sy=j; map[i][j]=0; } if(map[i][j]==3) { ex=i; ey=j; } } } step=inf; dfs(sx,sy,0,map); if(step!=inf&&step<=10) printf("%d\n",step); else printf("-1\n"); } }