poj 3009

来源:互联网 发布:microsoft办公软件 编辑:程序博客网 时间:2024/05/18 03:05

因为有对步数的限制,这个题可以直接暴力dfs。


需要注意的是,在选择方向的时候才加一个步数。能撞墙的前提得是,这个球是运动的。


#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 20 + 5;bool G[maxn][maxn];int r, c;struct node{    int x, y;    node(int a, int b): x(a), y(b) {}    node()    {        x = y = 0;    }} s, g;int ans;int dir[][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};bool is_right(int x, int y){    if(x <= r && x>= 1 && y <= c && y >= 1) return true;    return false;}void dfs(int x, int y, int m, int d){    if(m > 10) return;    //printf("%d %d %d\n", x, y, d);    if(x == g.x && y == g.y) {ans = min(ans, m); return;}    if(d == -1)    {        for(int i = 0; i < 4; i++)        {            int tx = x + dir[i][0];            int ty = y + dir[i][1];            if(is_right(tx, ty))            {                if(!G[tx][ty]) dfs(tx, ty, m + 1, i);            }        }    }    else    {        int tx = x + dir[d][0];        int ty = y + dir[d][1];        if(is_right(tx, ty))        {            if(G[tx][ty])            {                G[tx][ty] = 0;                dfs(x, y, m, -1);                G[tx][ty] = 1;            }            else dfs(tx, ty, m, d);        }    }}int main(){    while(scanf("%d%d", &c, &r) == 2 && r && c)    {        memset(G, 0, sizeof(G));        for(int i = 1; i <= r; i++)        {            for(int j = 1; j <= c; j++)            {                int t;                scanf("%d", &t);                if(t == 2) s = node(i, j);                else if(t == 3) g = node(i, j);                if(t == 1) G[i][j] = 1;            }        }        ans = maxn * maxn;        dfs(s.x, s.y, 0, -1);        printf("%d\n", ans == maxn * maxn ? -1 : ans);    }    return 0;}