POJ3009
题意:
冰壶游戏从2开始到3,直线走,出格子算输,打到障碍物才停下来,到终点也会停下来,<=10步到终点则算胜利,记录最小步数,失败输出-1.

思路:
dfs
于之前一步一步走的dfs不同的地方是,需要判断是否能走该方向,然后套一个while循环来一直走下去直到碰到1停下来或者碰到3记录答案。

反思:
我一开始做成了bfs,想嘛步数最小。
但实际上dfs也可以实现最小步数,每次到终点的时候对结果取min即可。
dfs所谓的一步不是代表只能走一格,而是代表可以走到下一个状态。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <map>
#include <stack>
#include <set>

using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll mod  = 1e9 + 7;
const ll maxn = 1e6 + 5;

int h,w,sx,sy,ex,ey;
int e[30][30];
int res;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};

void dfs(int x,int y,int z){
	if(z>10) return;
	for(int i=0;i<4;i++){
		int tx=x+dx[i];
		int ty=y+dy[i];
		int ok=0;//判断该方向是否能走 若能走ok为1
		while(e[tx][ty]!=1 && tx>=1 && tx<=h && ty>=1 && ty<=w){
			ok=1;
			if(tx==ex && ty==ey){
				if(z+1<res) res=z+1;
			}
			tx+=dx[i];
			ty+=dy[i];
		}
		if(e[tx][ty]==1 && ok){
			e[tx][ty]=0;
			dfs(tx-dx[i],ty-dy[i],z+1);
			e[tx][ty]=1;
		}
	}
}



int main(){
	while(cin>>w>>h &&w){
		memset(e,0,sizeof(e));
		for(int i=1;i<=h;i++){
			for(int j=1;j<=w;j++){
				cin>>e[i][j];
				if(e[i][j]==2) sx=i,sy=j;
				if(e[i][j]==3) ex=i,ey=j;
			}
		}
		res=INF;
		dfs(sx,sy,0);
		if(res>10) cout<<-1<<'\n';
		else cout<<res<<'\n';
	}
	return 0;
}