Fzu2124 - 吃豆人 BFS

來源:互聯網
上載者:User

標籤:

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 2XPB.3 2XP .S B.

Sample Output

1.21.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\n", ans);    }    return 0;}
View Code

 

Fzu2124 - 吃豆人 BFS

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.