zoukankan      html  css  js  c++  java
  • Fzu2124

    Description

    吃豆人是一款非常经典的游戏,游戏中玩家控制吃豆人在地图上吃光所有豆子,并且避免被怪物抓住。

    这道题没有怪物,将游戏的画面分成n*m的格子,每格地形可能为空地或者障碍物,吃豆人可以在空地上移动,吃豆人每移动一格需要1s时间,并且只能朝上下左右四个方向移动,特别的是吃豆人还能吐出舌头,舌头每移动一格需要0.1s时间,舌头只可以走直线。不必考虑吃豆人转身所需要的时间。

    举例,吃豆人在(1,1)坐标,而豆子在(1,5)坐标,并且中间没有障碍物,此时朝豆子方向吐舌头~,经过0.8s就可以吃到豆子(来回各0.4s,吐出去的舌头要缩回来的嘛)。

    游戏中还有加速道具,一旦得到加速道具,吃豆人就获得2倍移动速度,吐舌头的速度没有增加,即走1格用0.5s。现在地图上有且只有一颗豆子。游戏中有.代表空地;X表示障碍,吃豆人不能越过障碍;B代表豆子;S代表加速道具,并且地图上道具总数不超过1个,道具所在的位置为空地,得到道具后立即使用,道具立即消失,地形变为空地,不能用舌头去取道具;P表示吃豆人,吐舌头的时候吃豆人不能移动。

    Input

    输入包含多组数据。输入第一行有两个个整数n,m(2<=n,m<=20),接着一个n*m的地图矩阵。

    对于50%的数据,地图上没有道具。

    Output

    输出一行,最快用多少s吃到豆子,结果保留1位小数,如果吃不到,输出-1。

    Sample Input

    2 2
    XP
    B.
    3 2
    XP .
    S B.

    Sample Output

    1.2
    1.7
     
    思路:舌头是不能越过障碍的。由于道具最多只有一个,我们分两种情况,一是不拿道具,那么可先BFS出起点到各个点的最短距离,然后再枚举每个可以走到的位置,判断在该位置吐舌头能否得到更优解。二是从起点去拿道具,然后从道具那个位置出发,也BFS出道具到每个点的最短距离,考虑到达每个位置吐舌头能否得到更优解
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int n, m;
    char mat[25][25];
    
    int px, py, bx, by, sx, sy;
    
    
    struct node {
        int x, y;
        node() {}
        node(int x, int y) : x(x), y(y) {}
    };
    queue<node> que;
    int dir[][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
    int md[2][25][25], vis[25][25];
    void init() {
        memset(md, INF, sizeof md);
        sx = sy = -1;
        for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j) {
            if(mat[i][j] == 'P') px = i, py = j;
            if(mat[i][j] == 'B') bx = i, by = j;
            if(mat[i][j] == 'S') sx = i, sy = j;
        }
    }
    bool check(int x, int y) {
        if(x < 0 || x >= n || y < 0 || y >= m || vis[x][y] || mat[x][y] == 'X') return false;
        return true;
    }
    void BFS(int x, int y, int f) {
        while(!que.empty()) que.pop();
        memset(vis, 0, sizeof vis);
        vis[x][y] = 1;
        que.push(node(x, y));
        md[f][x][y] = 0;
        node u, v;
        while(!que.empty()) {
            u = que.front();
            que.pop();
            for(int i = 0; i < 4; ++i)
            {
                v.x = u.x + dir[i][0];
                v.y = u.y + dir[i][1];
                if(check(v.x, v.y)) {
                    que.push(v);
                    vis[v.x][v.y] = 1;
                    md[f][v.x][v.y] = md[f][u.x][u.y] + 1;
                }
            }
        }
    }
    double ans;
    
    int to(int x, int y) {
        if(bx == x) {
            int y1 = min(by, y), y2 = max(by, y);
            for(int i = y1 + 1; i <= y2; ++i) if(mat[x][i] == 'X') return -1;
            return y2 - y1;
        }else if(by == y) {
            int x1 = min(bx, x), x2 = max(bx, x);
            for(int i = x1 + 1; i <= x2; ++i) if(mat[i][y] == 'X') return -1;
            return x2 - x1;
        }
        return -1;
    }
    void solve1() {
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < m; ++j) if(md[0][i][j] != INF) {
                int dis = to(i, j);
                if(dis == -1) continue;
                ans = min(ans, md[0][i][j] + (double)dis * 0.1 * 2);
            }
        }
    }
    void solve2() {
        int res = md[0][sx][sy];
        if(res == INF) return;
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < m; ++j) if(md[1][i][j] != INF) {
                int dis = to(i, j);
                ans = min(ans, res + md[1][bx][by] / 2.0);
                if(dis != -1) ans = min(ans, res + md[1][i][j] / 2.0 + (double)dis * 0.1 * 2);
            }
        }
    }
    int main() {
        //freopen("in", "r", stdin);
        while(~scanf("%d%d", &n, &m)) {
            for(int i = 0; i < n; ++i) scanf("%s", mat[i]);
            init();
            BFS(px, py, 0);
            if(sx != -1)
            BFS(sx, sy, 1);
    
            ans = INF;
            if(md[0][bx][by] == INF) { puts("-1"); continue; }
            solve1();
            if(sx != -1)
            solve2();
            printf("%.1f
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java之jvm学习笔记五(实践写自己的类装载器)
    java之jvm学习笔记二(类装载器的体系结构)
    链式线性表
    java之jvm学习笔记十三(jvm基本结构)
    Java用户登陆界面
    李兴华JavaWeb开发笔记
    Java IO学习笔记:概念与原理
    Linux下一个简单的日志系统的设计及其C代码实现
    关于Core Location-ios定位
    C语言中main函数的參数具体解释
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/5453462.html
Copyright © 2011-2022 走看看