hdu1026(bfs+记录路径)

题意:给定一个迷宫n*m(1<=n,m<=100),求从(0,0)到(n-1,m-1)的最短时间,并且输出最短时间的路径。其中数字‘num',表示在这个格子中有怪物,需要消耗num(1<=num<=9)秒的时间去打败它,才能继续前进。并且走一步需要消耗1秒的时间。(’X'表示不能通过这个点,‘,'表示可以通过)

You may assume that the start position and the target position will never be a 'X', and there will never be a monster at the start position.

Sample Input

5 6
.XX.1.
..X.2.
2...X.
...XX.
XXXXX.
5 6
.XX.1.
..X.2.
2...X.
...XX.
XXXXX1
5 6
.XX...
..XX1.
2...X.
...XX.
XXXXX.

Sample Output

It takes 13 seconds to reach the target position, let me show you the way.
1s:(0,0)->(1,0)
2s:(1,0)->(1,1)
3s:(1,1)->(2,1)
4s:(2,1)->(2,2)
5s:(2,2)->(2,3)
6s:(2,3)->(1,3)
7s:(1,3)->(1,4)
8s:FIGHT AT (1,4)
9s:FIGHT AT (1,4)
10s:(1,4)->(1,5)
11s:(1,5)->(2,5)
12s:(2,5)->(3,5)
13s:(3,5)->(4,5)
FINISH
It takes 14 seconds to reach the target position, let me show you the way.
1s:(0,0)->(1,0)
2s:(1,0)->(1,1)
3s:(1,1)->(2,1)
4s:(2,1)->(2,2)
5s:(2,2)->(2,3)
6s:(2,3)->(1,3)
7s:(1,3)->(1,4)
8s:FIGHT AT (1,4)
9s:FIGHT AT (1,4)
10s:(1,4)->(1,5)
11s:(1,5)->(2,5)
12s:(2,5)->(3,5)
13s:(3,5)->(4,5)
14s:FIGHT AT (4,5)
FINISH
God please help our poor hero.
FINISH

思路:用广度优先搜索+优先队列就可以完成,难就难在记录路径。开一个数组,记录每一步的方向就可以了。输出的时候,用递归还原路径就可以了。
也是看了题解才懂的,感觉学到了很多。

#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;

const int MAX_N = 110;
int map[MAX_N][MAX_N];
int dir[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};//上、下、左、右
int path[MAX_N][MAX_N];//记录路径方向。0、1、2、3分别表示上下左右
int cnt[MAX_N][MAX_N];//相当于map的备份

struct node {
    int x;
    int y;
    int time;
    node(int x, int y, int time) {//构造方法
        this->x = x;
        this->y = y;
        this->time = time;
    }
};

//比较方法
struct nodecmp {
    bool operator()(const node &a, const node &b) {
        return a.time > b.time;
    }
};

int bfs(int n, int m) {
    memset(path, -1, sizeof(path));
    priority_queue<node, vector<node>, nodecmp> pq;
    pq.push(node(0, 0, 0) );
    map[0][0] = -1;
    while (pq.size()) {
        node tmp = pq.top();
        pq.pop();
        if (tmp.x == n - 1 && tmp.y == m - 1) return tmp.time;
        for (int i = 0; i < 4; ++i) {
            int nx = tmp.x + dir[i][0];
            int ny = tmp.y + dir[i][1];
            if (nx >= 0 && nx < n && ny >= 0 && ny < m && map[nx][ny] != -1) {
                int t = tmp.time + map[nx][ny] + 1;
                pq.push(node(nx, ny, t) );
                path[nx][ny] = i;//记录方向
                map[nx][ny] = -1;//标记为已经访问过
            }
        }
    }
    return 0;
}

int tt;
void print(int a, int b) {
    int nx = a - dir[path[a][b]][0];
    int ny = b - dir[path[a][b]][1];
    if (a == 0 && b == 0) return ;
    print(nx, ny);
    printf("%ds:(%d,%d)->(%d,%d)\n", ++tt, nx, ny, a, b);
    while (cnt[a][b]-- > 0) printf("%ds:FIGHT AT (%d,%d)\n", ++tt, a, b);
}

int main () {
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF) {
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j) {
                char c;
                scanf(" %c", &c);
                if (c == 'X') map[i][j] = -1;
                else if (c == '.') map[i][j] = 0;
                else map[i][j] = c - '0';
                cnt[i][j] = map[i][j];
            }
        int ans = bfs(n, m);
        if (ans) {
            tt = 0;
            printf("It takes %d seconds to reach the target position, let me show you the way.\n", ans);
            print(n - 1, m - 1);
        }
        else printf("God please help our poor hero.\n");
        printf("FINISH\n");
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容