d933. E. 傘兵
http://zerojudge.tw/ShowProblem?problemid=d933
內容 :
「報告將軍,有緊急狀況。」
「說!」
「前線遭遇伏擊,兄弟們死傷慘重,請求補給與增援。」
「嗯… 」
「將軍!我們不能白白讓他們送死啊!」
「……」
「將軍!」
「好吧,派出傘兵中隊空降支援前線!」
你的任務來了:
你手上有前線區域的地圖,地圖劃分為 R × C 的小格子。我們用 (r, c) 代表由北向南數來第 r 排,由西向東數來第 c 個小格子。你不知道前線部隊確切的位置,因為那是最高機密,不過你確定他們一定在地圖上的某處。然而,由於地形、天候、敵人視線等等因素,不是地圖上的每個地方都可以空降傘兵。可以空降的地方共有 N 個,座標分別是 (r1, c1), (r2, c2), · · · , (rN, cN)。
空降在每個的地方都有一些風險,用: v1, v2, · · · , vN 表示,值越大代表風險越高。空降下去的傘兵會知道前線部隊的確切位置,並且會往那個位置移動。傘兵可以從一個小格子移動到上下左右相鄰的小格子,而且每移動一格都會增加 1 單位的風險。這整個支援任務的總風險就是空降的風險加上傘兵移動的風險。
請你利用地圖和可以空降的地方的資料,算出派傘兵到地圖上每個地方的最小總風險。
輸入說明
:
第一行有一個整數 T ,代表接下來有幾組測試資料。兩筆測試資料中問會以一個空行隔開。
每一筆的第一行有 R C N 三個整數,意思如題目所述。接下來有 N 行,每行有三個整數 ri ci vi,代表第 i 個可以空降的地方的座標和風險。
1 ≤ R,C ≤ 100
1 ≤ N ≤ 1000
1 ≤ ri ≤ R, 1 ≤ ci ≤ C, 0 ≤ vi ≤ 10000
若 i ≠ j,則 (ri , ci) ≠ (rj , cj)
輸出說明
:
範例輸入 :
2 3 3 1 2 2 5 2 2 2 1 1 9 2 1 4
範例輸出 :
7 6 7 6 5 6 7 6 7 5 6 4 5
提示
:
出處
:
作法 : BFS
water fill
怕效率太差,將空降地點的風險由小排到大,適時地納入queue中
否則 對每一個點都做一次water fill 最慘是O(R*C*N)
/**********************************************************************************/
/* Problem: d933 "E. 傘兵" from 2010 NPSC 國中組初賽 */
/* Language: C */
/* Result: AC (24ms, 448KB) on ZeroJudge */
/* Author: morris1028 at 2011-06-12 20:31:43 */
/**********************************************************************************/
#include<stdio.h>
struct Queue {
int x, y;
}Q[10001];
struct coordinate{
int t, x, y;
}set[1001], X[1001];
void Merge(int l, int m, int h) {
int In1 = l, In2 = m+1;
int a, b, Top=0;
while(In1 <= m && In2 <= h)
if(set[In1].t < set[In2].t)
X[Top++] = set[In1++];
else X[Top++] = set[In2++];
while(In1 <= m) X[Top++] = set[In1++];
while(In2 <= h) X[Top++] = set[In2++];
for(a = 0, b = l; a < Top; a++, b++)
set[b] = X[a];
}
void MergeSort(int l, int h) {
if(l < h) {
int m = (l+h)/2;
MergeSort(l , m);
MergeSort(m+1, h);
Merge(l, m, h);
}
}
main() {
int T, R, C, N, r, c, v, a, b;
scanf("%d", &T);
while(T--) {
scanf("%d %d %d", &R, &C, &N);
int Map[101][101];
for(a = 0; a < N; a++) {
scanf("%d %d %d", &r, &c, &v);
Map[r][c] = v;
set[a].t = v, set[a].x = r, set[a].y = c;
}
MergeSort(0, N-1);
int Qt = 0, Used[101][101] = {}, tx, ty, ins = 1;
Q[0].x = set[0].x, Q[0].y = set[0].y, Used[Q[0].x][Q[0].y] = 1;
for(a = 0; a <= Qt; a++) {
tx = Q[a].x, ty = Q[a].y;
while(ins < N && Map[tx][ty] == set[ins].t) {
Q[++Qt].x = set[ins].x, Q[Qt].y = set[ins++].y;
Used[Q[Qt].x][Q[Qt].y] = 1;
}
if(tx+1<= R && Used[tx+1][ty] == 0) {
Used[tx+1][ty] = 1;
Map[tx+1][ty] = Map[tx][ty]+1;
Q[++Qt].x = tx+1, Q[Qt].y = ty;
}
if(ty+1<= C && Used[tx][ty+1] == 0) {
Used[tx][ty+1] = 1;
Map[tx][ty+1] = Map[tx][ty]+1;
Q[++Qt].x = tx, Q[Qt].y = ty+1;
}
if(tx-1>=1 && Used[tx-1][ty] == 0) {
Used[tx-1][ty] = 1;
Map[tx-1][ty] = Map[tx][ty]+1;
Q[++Qt].x = tx-1, Q[Qt].y = ty;
}
if(ty-1>=1 && Used[tx][ty-1] == 0) {
Used[tx][ty-1] = 1;
Map[tx][ty-1] = Map[tx][ty]+1;
Q[++Qt].x = tx, Q[Qt].y = ty-1;
}
}
for(a = 1; a <= R; puts(""), a++)
for(b = 1; b <= C; b++)
printf("%d ", Map[a][b]);
}
return 0;
}
上一篇:d932. D. 流水不腐