poj 3009 Curling 2.0 dfs
dfs
题意:已知起点和终点,求石子从起点到达终点的最短路,如果无法到达,则输出-1。石子移动的具体规则如下:
1、开始时,石子在起点s处
2、运动方向可以是水平或垂直的,不能斜方向运动
3、最开始的时候,你可以将石子向上下左右任意一个方向抛,如果与它相邻的点是障碍物的话除外
4、一旦石子开始运动,有三种可能:
a、遇到障碍物,石子会停在障碍物的前一格,障碍物会消失
b、如果出界,游戏失败
c、到达终点,游戏结束并成功
5、如果移动的次数超过10次,将认为游戏是失败的
把考虑的情况放进去就行了
View Code
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int maxn = 22; int dir[4][2] = { {0,1},{0,-1},{1,0},{-1,0} }; int R , C; int map[maxn][maxn]; bool inMap(int r, int c) { return r>=1 && r<=R && c>=1 && c<=C; } int ans; void dfs(int r,int c,int step) { if(step>10 || step>ans) return; for(int i=0;i<4;i++) { int rr = r + dir[i][0]; int cc = c + dir[i][1]; if(map[rr][cc] == 1) continue; while(inMap(rr,cc) && map[rr][cc]==0) { rr += dir[i][0]; cc += dir[i][1]; } if(!inMap(rr,cc)) continue; if(map[rr][cc] == 3) { if(step < ans) ans = step; return; } map[rr][cc] = 0; dfs( rr - dir[i][0] , cc - dir[i][1] , step+1 ); map[rr][cc] = 1; } return; } int main() { while(~scanf("%d%d",&C,&R) && R+C) { int sr , sc; for(int i=1;i<=R;i++) for(int j=1;j<=C;j++) { scanf("%d",&map[i][j]); if(map[i][j] == 2) { sr = i; sc = j; map[i][j] = 0; } } ans = (1<<29); dfs(sr,sc,1); if(ans == (1<<29)) ans = -1; printf("%d\n",ans); } return 0; }