HDU 1026 Ignatius and the Princess I

Name:Ignatius and the Princess I
P_ID:HDU 1026
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026

题意描述:
就是普通迷宫加上一些权重。另外要输出路径。

题目分析:
本题的难点在于路径的输出。为了达到按序输出路径,本题除了要使用优先队列求得bfs最短路之外,还要用栈stack来输出路径。

本题的输出采用栈结构,这是一种输出路径的经典做法。要好好揣摩。
注意到本题采用的是优先队列,而不是普通队列。在路径存在权重的时候,就不能用普通队列了,就需要用优先队列。

思路附在代码注释中:

参考代码:


/**
 * method2: priority_queue最短路 + stack输出
 * P_ID: HDU 1026
 * date: 2016-04-22
 * level: dificult
 */
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <stack>

using namespace std;


int N, M;
struct cell {
    int x;
    int y;
    int time;
    //重载小于号,使之满足priority_queue的排序要求
    friend bool operator < (const cell& a, const cell &b)
    {
        return a.time > b.time;
    }
}path[105][105];
char maze[105][105];
int vis[105][105];
const int dir[][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
int ansTime;



bool check(int x, int y)
{
    if(x<0 || y<0 || x>=N || y>=M) return false;
    if(maze[x][y]=='X') return false;
    return true;
}

int bfs(cell s)
{
    priority_queue<cell> myCell;
    myCell.push(s);
    vis[0][0] = 1;
    while (!myCell.empty())
    {
        cell head = myCell.top();
        myCell.pop();
        //终止条件,第一次到这里一定是最短路径
        if(head.x==N-1 && head.y==M-1)
            return head.time;
        for(int i=0; i<4; ++i)
        {
            int xx = head.x + dir[i][0];
            int yy = head.y + dir[i][1];
            if(check(xx, yy) && !vis[xx][yy])
            {
                vis[xx][yy] = 1;
                //以下三行,用来存储路径,注意这里不是用想当然的字符串string也不是用一个vector不断的push进去(会浪费大量空间,同时极不方便后续输出),而是采用一个与迷宫一样大的二维数组,每个grid内存的是其父grid,也就是来路
                path[xx][yy].x = head.x;
                path[xx][yy].y = head.y;
                path[xx][yy].time = head.time + 1;
                //下一步
                cell next;
                next.x = xx;
                next.y = yy;
                next.time = head.time + 1;//注意,就算是怪兽,也有一个移动到这里的时间1,相当于打怪兽花的时间是另外加上算的
                if(maze[xx][yy]=='.') myCell.push(next);
                else
                {
                    //maze是char类型,要进行转换
                    next.time = next.time + maze[xx][yy] - '0';
                    myCell.push(next);
                }
           }
        }
    }
    return -1;//到不了终点了,营救失败
}


void print()
{
    if(ansTime==-1) printf("God please help our poor hero.\n");
    else
    {
        printf("It takes %d seconds to reach the target position, let me show you the way.\n", ansTime);
        stack<cell> st;
        cell t = path[N-1][M-1];
        //终点位置需要单独最先入栈,因为没有任何位置存的父节点是最终位置
        cell rMin;
        rMin.x = N-1;
        rMin.y = M-1;
        rMin.time = ansTime;
        st.push(rMin);
        while (t.x||t.y)//只有当t.x==t.y==0才为假
        {
            st.push(t);
            t = path[t.x][t.y];
        }
        int k=1;
        while (!st.empty())
        {
            t = st.top();
            st.pop();
            printf("%ds:(%d,%d)->(%d,%d)\n", k++, path[t.x][t.y].x, path[t.x][t.y].y, t.x, t.y);
            if(maze[t.x][t.y]!='.')
            {
                int tmp = maze[t.x][t.y] - '0';
                while(tmp--)
                {
                    printf("%ds:FIGHT AT (%d,%d)\n", k++, t.x, t.y);
                }
            }

        }
    }
    printf("FINISH\n");
    return;
}

int main()
{
    while (~scanf("%d%d", &N, &M))
    {
        ansTime = 999999;
        memset(maze, 0, sizeof(maze));
        memset(vis, 0, sizeof(vis));
        for(int i=0; i<N; ++i)
            scanf("%s", maze[i]);
        cell start;
        start.x = 0;
        start.y = 0;
        start.time = 0;
        ansTime = bfs(start);
        print();
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值