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;
}