hdu 1026 Ignatius and the Princess I

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1026

題目大意:求用時最短路線並打印路徑,n表示用n秒打敗怪獸。

題目分析:bfs+優先隊列求出最短用時,path數組記錄路徑,棧輸出路徑。

代碼參考:

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

const int N = 109;
priority_queue<int> pq;//優先隊列
struct Node
{
    int x, y, step;
    friend bool operator < (const Node &a, const Node &b) { //定義排序規則
        return a.step > b.step;
    }
}p[N][N],path[N][N];
char edge[N][N];//保存地圖
bool vis[N][N];
int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int n, m, minStep;

int bfs(Node s)
{
    priority_queue<Node> Q;
    Q.push(s);
    vis[0][0] = 1;
    while(!Q.empty()) {
        Node head = Q.top();
        Q.pop();
        if(head.x == n - 1 && head.y == m - 1) { //如果走到了終點,返回最短用時
            return head.step;
        }
        for(int i = 0; i < 4; ++ i) { //枚舉4個方向
            int x = head.x + dir[i][0];
            int y = head.y + dir[i][1];
            if(x >= 0 && x < n && y >= 0 && y < m && edge[x][y] != 'X' && !vis[x][y]) { //判定是否可走
                vis[x][y] = 1;
                path[x][y].x = head.x; //保存路徑
                path[x][y].y = head.y;
                path[x][y].step = head.step + 1;
                Node t; //當前點
                t.x = x;
                t.y = y;
                t.step = head.step + 1;
                if(edge[x][y] == '.') {
                    Q.push(t);
                } else {
                    t.step = t.step + edge[x][y] - '0'; //加上打怪獸的時間
                    Q.push(t);
                }
            }
        }
    }
    return -1; //如果沒有走到終點
}

void print()
{
    if(minStep == -1) { //如果沒有走到終點
        puts("God please help our poor hero.");
    } else { //輸出最短用時
        printf("It takes %d seconds to reach the target position, let me show you the way.\n", minStep);
        stack<Node> st; //棧輸出
        Node t = path[n - 1][m - 1];
        Node rmin;
        rmin.x = n - 1;
        rmin.y = m - 1;
        rmin.step = minStep;
        st.push(rmin);
        while(t.x || t.y) { //如果到了終點
            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(edge[t.x][t.y] != '.') {
                int fight = edge[t.x][t.y] - '0';
                while(fight --) {
                    printf("%ds:FIGHT AT (%d,%d)\n", k ++, t.x, t.y);
                }
            }
        }
    }
    puts("FINISH");
    return;
}

int main()
{
    while(~scanf("%d%d", &n, &m)) {
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < n; ++ i) {
            scanf("%s", edge[i]);
        }
        Node start; //起點
        start.x = start.y = start.step = 0;
        minStep = bfs(start);
        print(); //打印路徑
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章