# 題目: UVa 929 - Number Maze
# 題目說明
給你一張 N * M
的 map,每格都會有值
求起點到終點 (左上到右下) 的最小數字和
INPUT:
第一行有一個整數 T
,代表有 T
筆測資
每筆測資第一行有兩個整數 N
、 M
,代表 map 的大小
接著會有 N
行,每行有 M
個整數,代表 map 的值
OUTPUT:
輸出從起點到終點 (左上到右下) 的最小數字和
# 解題方法
先建 map
,接著以 dijkstra
演算法搭配 priority_queue
建出起點到每一個點的最小路徑
最後輸出終點的值即可
# 參考程式碼
#include <iostream> | |
#include <memory.h> | |
#include <queue> | |
#include <tuple> | |
using namespace std; | |
typedef tuple<int, int, int> tp; | |
int N, M; | |
int map[1001][1001]; | |
int vals[1001][1001]; | |
bool vis[1001][1001]; | |
int d[4][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} }; | |
priority_queue< tp, vector<tp>, greater<tp> > pq; | |
void dijkstra() | |
{ | |
vals[0][0] = map[0][0]; | |
pq.push(make_tuple(map[0][0], 0, 0)); | |
while (!pq.empty()) | |
{ | |
auto [val, x, y] = pq.top(); | |
pq.pop(); | |
vis[x][y] = true; | |
for (int i = 0; i < 4; ++i) | |
{ | |
int nx = x + d[i][0]; | |
int ny = y + d[i][1]; | |
if (nx >= 0 && nx < N && ny >= 0 && ny < M && !vis[nx][ny]) | |
{ | |
int tmp = val + map[nx][ny]; | |
if (vals[nx][ny] == -1 || vals[nx][ny] > tmp) | |
{ | |
vals[nx][ny] = tmp; | |
pq.push(make_tuple(tmp, nx, ny)); | |
} | |
} | |
} | |
} | |
cout << vals[N - 1][M - 1] << "\n"; | |
} | |
int main() | |
{ | |
// fast io | |
ios::sync_with_stdio(false); | |
cin.tie(nullptr); | |
cout.tie(nullptr); | |
int T; | |
cin >> T; | |
while (T--) | |
{ | |
cin >> N >> M; | |
// init | |
memset(map, 0, sizeof(map)); | |
memset(vis, false, sizeof(vis)); | |
memset(vals, -1, sizeof(vals)); | |
// store data in map | |
for (int i = 0, val; i < N; ++i) for (int j = 0; j < M; ++j) | |
{ | |
cin >> val; | |
map[i][j] = val; | |
} | |
// dijkstra algorithm | |
dijkstra(); | |
} | |
return 0; | |
} |
# 參考資料
https://www.larrysprognotes.com/UVa%20-%20929/