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);
}