Ignatius and the Princess I HDU - 1026 BFS+优先队列+记录路径

16 篇文章 0 订阅

求迷宫最短路径长度和路径。由于有些点会停留打怪,需要多增加停留的时间,而不只是加1。由于队列中每一个扩展点的权重不一样,所以不能按平常的BFS解题。这里采用优先队列,权重大也就是耗时耗路径少的点优先出队。题目还有一个难点就是最短路径。由于BFS就是查找最短路径,所以出列的点构成的路径就是最短路径,我们可以从终点开始往起点搜索,记录扩展点的后继,最后在从起点扩展后继遍历输出到终点。

这里使用功能C++STL的优先队列 priority_queue

优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。

优先级队列可以用向量(vector)或双向队列(deque)来实现(注意list container不能用来实现queue,因为list的迭代器不是任意存取iterator,而pop中用到堆排序时是要求randomaccess iterator 的!):
priority_queue<vector<int>, less<int> > pq1;     // 使用递增less<int>函数对象排序
priority_queue<deque<int>, greater<int> > pq2;   // 使用递减greater<int>函数对象排序
其成员函数有“判空(empty)” 、“尺寸(Size)” 、“栈顶元素(top)” 、“压栈(push)” 、“弹栈(pop)”等。
在这里插入图片描述

#include <queue>
#include <iostream>
#include <cstring>
#include <cstdio>
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int MAXN = 105;
char maze[MAXN][MAXN];//迷宫
int vis[MAXN][MAXN];//判断访问数组,1为已经访问,0为未访问
int n, m;//行、列
int dx[] = {1, 0, -1, 0};//方向矢量
int dy[] = {0, -1, 0, 1};
struct Point
{
    int x, y, time;//坐标和花费的时间
    bool operator < (const Point& a) const
    {
        return time > a.time;
    }
};
struct nextnode
{
    int x, y;
}Next[MAXN][MAXN];//后继数组
bool bfs(int x, int y)
{
    vis[x][y] = 1;
    Next[x][y].x = -1;//终点无后继
    priority_queue<Point> q;
    Point cur, tmp;
    cur.x = x; cur.y = y; cur.time = 0;
    if (isdigit(maze[x][y])) cur.time += maze[x][y] - '0';//终点可以有野怪,如果是数字字符,打怪停留
    q.push(cur);
    while (!q.empty())
    {
        cur = q.top();
        q.pop();
        if (cur.x == 0 && cur.y == 0)//到达起点
        {
            int sx = cur.x, sy = cur.y;
            int t = 1;
            printf("It takes %d seconds to reach the target position, let me show you the way.\n", cur.time);
            while (Next[sx][sy].x != -1)
            {
                int nx = Next[sx][sy].x, ny = Next[sx][sy].y;
                printf("%ds:(%d,%d)->(%d,%d)\n", t++, sx, sy, nx, ny);
                if (isdigit(maze[nx][ny]))
                    _for (i, 0, maze[nx][ny] - '0')
                        printf("%ds:FIGHT AT (%d,%d)\n", t++, nx, ny);
                sx = nx;
                sy = ny;
            }
            return true;
        }
        _for (i, 0, 4)
        {
            int nx = cur.x + dx[i];
            int ny = cur.y + dy[i];
            if (nx < 0 || nx >= n || ny < 0 || ny >= m || vis[nx][ny] || maze[nx][ny] == 'X') continue;
            vis[nx][ny] = 1;
            tmp.x = nx; tmp.y = ny; tmp.time = cur.time + 1;
            if (isdigit(maze[nx][ny])) tmp.time += maze[nx][ny] - '0';
            //tmp的后继为cur点,不能设置前驱数组,因为cur的前驱有多个(多个扩展点在队列中)
            Next[nx][ny].x = cur.x;
            Next[nx][ny].y = cur.y;
            q.push(tmp);
        }
    }
    return false;
}
int main()
{
    while (cin >> n >> m)
    {
        memset(vis, 0, sizeof(vis));
        _for (i, 0, n) _for (j, 0, m) cin >> maze[i][j];
        if (!bfs(n - 1, m - 1)) cout << "God please help our poor hero.\n";
        cout << "FINISH\n";
    }
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 智慧社区背景与挑战 随着城市化的快速发展,社区面临健康、安全、邻里关系和服务质量等多方面的挑战。华为技术有限公司提出智慧社区解决方案,旨在通过先进的数字化技术应对这些问题,提升城市社区的生活质量。 2. 技术推动智慧社区发展 技术进步,特别是数字化、无线化、移动化和物联化,为城市社区的智慧化提供了可能。这些技术的应用不仅提高了社区的运行效率,也增强了居民的便利性和安全性。 3. 智慧社区的核心价值 智慧社区承载了智慧城市的核心价值,通过全面信息化处理,实现对城市各个方面的数字网络化管理、服务与决策功能,从而提升社会服务效率,整合社会服务资源。 4. 多层次、全方位的智慧社区服务 智慧社区通过构建和谐、温情、平安和健康四大社区模块,满足社区居民的多层次需求。这些服务模块包括社区医疗、安全监控、情感沟通和健康监测等。 5. 智慧社区技术框架 智慧社区技术框架强调统一平台的建设,设立数据中心,构建基础网络,并通过分层建设,实现平台能力及应用的可持续成长和扩展。 6. 感知统一平台与服务方案 感知统一平台是智慧社区的关键组成部分,通过统一的RFID身份识别和信息管理,实现社区服务的智能化和便捷化。同时,提供社区内外监控、紧急救助服务和便民服务等。 7. 健康社区的构建 健康社区模块专注于为居民提供健康管理服务,通过整合医疗资源和居民接入,实现远程医疗、慢性病管理和紧急救助等功能,推动医疗模式从治疗向预防转变。 8. 平安社区的安全保障 平安社区通过闭路电视监控、防盗报警和紧急求助等技术,保障社区居民的人身和财产安全,实现社区环境的实时监控和智能分析。 9. 温情社区的情感沟通 温情社区着重于建立社区居民间的情感联系,通过组织社区活动、一键呼叫服务和互帮互助平台,增强邻里间的交流和互助。 10. 和谐社区的资源整合 和谐社区作为社会资源的整合协调者,通过统一接入和身份识别,实现社区信息和服务的便捷获取,提升居民生活质量,促进社区和谐。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值