zoukankan      html  css  js  c++  java
  • 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.
    ", mintime);
    
        int count = 0;
        v1 = s.top();
        s.pop();
        while(!s.empty()) {
            v2 = s.top();
            s.pop();
            printf("%ds:(%d,%d)->(%d,%d)
    ", ++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)
    ", ++count, v2.row, v2.col);
            }
    
            v1 = v2;
        }
    }
    
    char mygetchar()
    {
        char c;
    
        while((c = getchar()) && (c == ' ' || c == '	' || c == '
    '));
    
        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.
    ");
            printf("FINISH
    ");
        }
    
        return 0;
    }


  • 相关阅读:
    两种方法实现超出省略号效果
    CSS中定义优先权
    网页设计中字体设置详解
    JavaScript的方法和技巧
    手把手教你使用Gene6FTP远程管理
    用Zend Encoder加密PHP文件和PHP 优化配置
    JavaScript的方法和技巧
    SQL Server 2000订阅与发布的具体操作
    企业级邮件服务软件推荐
    用Zend Encoder加密PHP文件和PHP 优化配置
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564379.html
Copyright © 2011-2022 走看看