HDU1026 Ignatius and the Princess I

问题链接HDU1026 Ignatius and the Princess I

题意简述:从矩阵的左上角走到右下角所需的最短时间,并且要求输出走的过程。矩阵中"."是可以走的,"X"是墙,n(数字1-9)是怪兽,需要战斗数字所示的时间。对于每个测试实例,先输入n和m,分别表示行数和列数,然后输入矩阵。

问题分析:显然求最短路径问题用BFS,另外由于有怪兽,所以搜索过程需要使用优先队列。一个典型的用分支限界法解决的问题。最小路径上每个点到出发点距离应该是最小的。

程序说明:用节点矩阵grid[][]存储输入的矩阵,同时存储输入的矩阵和到起始点需要行走的最少步骤,以及最小路径上前一个节点坐标。这个程序运行时间上算是比较短的。

AC的C++语言程序如下:

/* HDU1026 Ignatius and the Princess I */

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>

using namespace std;

#define DIRECTSIZE 4

struct direct {
    int drow;
    int dcol;
} direct[DIRECTSIZE] =
    {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};

const int MAXN = 100;
const unsigned int MAXTIME = MAXN*MAXN*9+1;

struct gridnode {
    char v;
    int prevrow, prevcol;
    unsigned int mintime;
};

gridnode grid[MAXN+1][MAXN+1];

struct node {
    int row, col;
    unsigned int sumtime;

    bool operator<(const node n) const {
        return sumtime > n.sumtime;
    }
};

int n, m;
unsigned int mintime;
node start, end2, f, v;

int bfs()
{
    int ans = 0;

    grid[0][0].prevrow = -1;
    grid[0][0].prevcol = -1;
    grid[0][0].mintime = 0;

    start.row = 0;
    start.col = 0;
    start.sumtime = 0;

    end2.row = n - 1;
    end2.col = m - 1;

    mintime = MAXTIME;

    priority_queue<node> q;
    q.push(start);

    while(!q.empty()) {
        f = q.top();
        q.pop();

        if(f.row == end2.row && f.col == end2.col) {
            if(f.sumtime < mintime) {
                mintime = f.sumtime;
                ans = 1;
                continue;
            }
        }

        if(f.sumtime >= mintime)
            continue;

        for(int i=0; i<DIRECTSIZE; i++) {
            int nextrow = f.row + direct[i].drow;
            int nextcol = f.col + direct[i].dcol;

            if(0 <= nextrow && nextrow < n && 0 <= nextcol && nextcol < m) {
                if(grid[nextrow][nextcol].v == '.') {
                    // 曾经走过的点,这次时间长的话就不再走了
                    if(f.sumtime + 1 < grid[nextrow][nextcol].mintime) {
                        v.row = nextrow;
                        v.col = nextcol;
                        v.sumtime = f.sumtime + 1;
                        grid[v.row][v.col].mintime = v.sumtime;
                        grid[v.row][v.col].prevrow = f.row;
                        grid[v.row][v.col].prevcol = f.col;
                        q.push(v);
                    }
                } else if(grid[nextrow][nextcol].v != 'X') {
                    v.sumtime = f.sumtime + 1;
                    v.sumtime += grid[nextrow][nextcol].v - '0';
                    // 曾经走过的点,这次时间长的话就不再走了
                    if(v.sumtime < grid[nextrow][nextcol].mintime) {
                        v.row = nextrow;
                        v.col = nextcol;
                        grid[v.row][v.col].mintime = v.sumtime;
                        grid[v.row][v.col].prevrow = f.row;
                        grid[v.row][v.col].prevcol = f.col;
                        q.push(v);
                    }
                }
            }
        }
    }

    return ans;
}

void output_print()
{
    stack<node> s;
    node v1, v2;

    v.row = end2.row;
    v.col = end2.col;
    s.push(v);
    while(grid[v.row][v.col].prevrow != -1 || grid[v.row][v.col].prevcol != -1) {
        v2 = v;
        v.row = grid[v2.row][v2.col].prevrow;
        v.col = grid[v2.row][v2.col].prevcol;
        s.push(v);
    }

    printf("It takes %d seconds to reach the target position, let me show you the way.\n", mintime);

    int count = 0;
    v1 = s.top();
    s.pop();
    while(!s.empty()) {
        v2 = s.top();
        s.pop();
        printf("%ds:(%d,%d)->(%d,%d)\n", ++count, v1.row, v1.col, v2.row, v2.col);
        if(grid[v2.row][v2.col].v != '.') {
            for(int j=1; j<=grid[v2.row][v2.col].v-'0'; j++)
                printf("%ds:FIGHT AT (%d,%d)\n", ++count, v2.row, v2.col);
        }

        v1 = v2;
    }
}

char mygetchar()
{
    char c;

    while((c = getchar()) && (c == ' ' || c == '\t' || c == '\n'));

    return c;
}

int main()
{
    while(scanf("%d%d", &n, &m) != EOF) {
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++) {
                grid[i][j].v = mygetchar();
                grid[i][j].mintime = MAXTIME;
            }

        int ans = bfs();

        if(ans)
            output_print();
        else
            printf("God please help our poor hero.\n");
        printf("FINISH\n");
    }

    return 0;
}
时间: 2024-12-29 11:27:22

HDU1026 Ignatius and the Princess I的相关文章

hdu1026 Ignatius and the Princess I(BFS+优先队列)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1026 Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13944    Accepted Submission(s): 4381 Special Judge Problem Descri

HDU1026 Ignatius and the Princess I 【BFS】+【路径记录】

Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 11710    Accepted Submission(s): 3661 Special Judge Problem Description The Princess has been abducted by the BEelzeb

hdu 1026 Ignatius and the Princess I(bfs搜索+输出路径)

题目来源:hdu-1026 Ignatius and the Princess I Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 14677 Accepted Submission(s): 4653 Special Judge Problem Description The Princ

HDU 1029: Ignatius and the Princess IV

Ignatius and the Princess IV ///@author Sycamore ///@date 8/8/2017 #include<bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(0); int n; while (cin >> n) { map<int, int>v; int t,ans=-1; for (int i = 1;

(全排列)Ignatius and the Princess II -- HDU -- 1027

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1027 Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5822    Accepted Submission(s): 3433 Problem Description Now our h

HDU 1027 Ignatius and the Princess II

原题代号:HDU 1027 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1027 原题描述: Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8415    Accepted Submission(s): 4955 Problem

HDU1029 Ignatius and the Princess IV

问题链接:HDU1029 Ignatius and the Princess IV.基础练习题,用C++语言编写. 题意简述:输入n(n是奇数),然后输入n个整数,求出现(n+1)/2次的整数. 问题分析:n是奇数,(n+1)/2是n的一半以上,只要将n个数据排序,出现(n+1)/2次的整数必然会出现在中间位置. 本问题使用C++语言编写的原因是函数sort()的参数简单,使用方便. AC的C++语言程序如下: /* HDU1029 Ignatius and the Princess IV */

[2016-03-27][HDU][1029][Ignatius and the Princess IV]

时间:2016-03-30 22:03:01 星期三 题目编号:[2016-03-27][HDU][1029][Ignatius and the Princess IV] 题目大意:给定n个数字,输出其中出现次数超过n/2的数字 #include <algorithm> #include <cstdio> using namespace std; const int maxn = 1E6 + 10; int a[maxn]; int main(){ int n; while(~sc

Ignatius and the Princess IV

Ignatius and the Princess IV Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32767 K (Java/Others)Total Submission(s): 24410    Accepted Submission(s): 10261 Problem Description "OK, you are not too bad, em... But you can never pass the