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;
}
posted @ 2012-06-30 18:26  lenohoo  阅读(154)  评论(0编辑  收藏  举报