3kyu Path Finder #3: the Alpinist

3kyu Path Finder #3: the Alpinist

题目背景:

Task
You are at start location [0, 0] in mountain area of NxN and you can only move in one of the four cardinal directions (i.e. North, East, South, West). Return minimal number of climb rounds to target location [N-1, N-1]. Number of climb rounds between adjacent locations is defined as difference of location altitudes (ascending or descending).
Location altitude is defined as an integer number (0-9).

题目分析:

本道题乍一看无从下手,但是仔细分析下,题目可以这么认为:地图中有许多格点,每个格点有一座山,山的高度从0 - 9, 从起点那座山开始,翻过n座山后,到达终点那座山,要求找一条可以使得翻上翻下的高度最矮的爬山路径。我们可以把山与山之间的高度差抽象为各个格点的距离,那么题目就转换为最短路径问题,不过本道题比较卡数据,所以纯粹的Dij算法是会超时的,需要加上堆优化,算是改进版的dij算法。本质上这道题的思路很简单,不过dij算法码起来比较麻烦,个人感觉记住这个模板题即可。

AC代码:

#include <cmath>
#include <queue>
// solve the shortest path --> Dijkstra algorithm
int V; // real nums of vertices
const int NUM = 50000;  // set the maximum nums of vertices is 50000
int go[4][2] = {
    0, 1,
    1, 0,
    0, -1,
    -1, 0
};

struct node{ 
    int next, c; 
    bool operator<(const node &o) const{
        return c > o.c;
    }
}; 

int dijkstra(std::vector<node> edge[NUM], int src) { 
    std::priority_queue<node> Q; 
    std::vector<int>dist(V, -1);
    dist[src] = 0; 
    node tmp;
    tmp.next = src;
    tmp.c = dist[src];
    Q.push(tmp);
    
    while ( !Q.empty() ) { 
        tmp = Q.top();
        Q.pop();
        int u = tmp.next;
        if ( u == V - 1 ) return dist[u];
        for (int i = 0; i < edge[u].size(); i++) {
            int v = edge[u][i].next;
            int c = edge[u][i].c;
            if (dist[v] == -1 || dist[u] + c < dist[v]){
                dist[v] = dist[u] + c; 
                tmp.c = dist[v], tmp.next = v;
                Q.push(tmp);
            }
        }
     } 
     return dist[V - 1];
}

int path_finder(std::string maze) {
    int length = std::floor( std::sqrt( (double) maze.size() ) );
    std::cout << length << std::endl;
    V = length * length;
    std::vector<node> edge[NUM];
    for ( int i = 0; i < V; i++ ) edge[i].clear();
    for ( int x = 0; x < length; x++ ) {
        for ( int y = 0; y < length; y++ ) {
            for ( int i = 0; i < 4; i++ ) {
                int nx = x + go[i][0];
                int ny = y + go[i][1];
                if ( nx < 0 || nx >= length || ny < 0 || ny >= length ) continue;
                node tmp;
                tmp.next = nx * length + ny;
                tmp.c = std::abs(maze[nx * ( length + 1 )+ ny] - maze[x * ( length + 1 ) + y]);
                edge[x * length + y].push_back(tmp);
            }
        }
    }
    
    int src = 0;
    return dijkstra(edge, src); 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值