[ZPG TEST 109] 兔子跳跃【构图】
兔子跳躍
(jumping.pas/c/cpp)
【問題描述】
兔子常常感到孤獨,所以當他們決定出去走走,去見見他們的朋友,他們跳的很快。
?
Iris正走在一條無限長的直線道路上。這條道路上點的編號...,-3,-2,-1,0,1,2,3,...從西到東。Iris的家是在0點上,而她想要見的朋友在點1000000001。她是兔子當然只能通過移動跳躍前行,她有兩個跳躍類型:小跳和大跳。當她在點x,通過一小跳,她可以移動到點(x + 2)或(x - 2)。通過一個大跳躍,她可以移動到點(x + largeJump)或點(x - largeJump)。
?
不幸的是,道路總是那么坑坑洼洼,洞的大小不一,有些還可能包含連續幾個點,Iris不能跳到這些洞中。
?
Iris喜歡用小跳,因為這樣更加的省力。請問到達1000000001所要使用的最少的大跳躍數量。如果不能達到這一點,輸出-1。
?
注意,道路無限長,當然能跳到超過1000000001的點。
?
【輸入】
輸入文件名為jumping.in。
有多組測試數據:
第一行,包含一個整數Num,表示測試數據的個數。(1<=Num<=10)
每組測試數據,
第一行一個整數N,表示共有N個洞。1<=N<=25.
接下來一行N*2個整數,每個洞的兩個端點編號,所有端點都是嚴格遞增順序給出。[1 and 1,000,000,000]。
最后一個整數largeJump[3 and 1,000,000,000]。
?
【輸出】
輸出文件jumping.out共Num行,
到達目標所需最少大跳躍的次數。無法到達輸出-1
?
【輸出輸出樣例】
| jumping.in | jumping.out |
| 5 1 1 2 3 1 1 2 4 1 2 3 3 4 2 17 21 36 40 55 59 74 19 12 187640193 187640493 187640738 187640845 564588641 564588679 ? 564588696 564588907 605671187 605671278 605671288 605671386 ? 755723729 755723774 755723880 755723920 795077469 795077625 ? 795077851 795078039 945654724 945654815 945655107 945655323 475 | 1 -1 3 5 9 ? |
【說明】
第一組樣例中
0 => 3 -> 5 -> 7 -> ... -> 999999999 -> 1000000001
從0到3使用了一次大跳躍。
第二組樣例中,她只能跳到偶數的位置,不可能到達目標。
第三組樣例中,0 -> -2 => 1 => 4 => 7 -> 9 -> 11 -> ... -> 999999999 -> 1000000001?
?
?
乍一看以為是需要離散化的dp,可是這里的大跳躍步數不是定值,所以難以做到。
這一題其實可以構建圖論模型!注意到小跳躍是沒有代價的,而且小跳躍之后所在節點奇偶性不變。由于每個洞是不能進入的,所以可以把每段可以走的路作為節點,再把這個節點拆成兩個點,其中一個表示這段能走的路的奇數點,另一個表示偶數點。然后枚舉每對節點,如果可以從i節點大跳躍到j節點,則連邊。最后求一次最短路就ok!由于是不加權的圖,用bfs就可以了。
#include <cstdio> #include <cstring>const int des = 1000000001;int T, n, lj, x[30], y[30], TT, tx1, ty1, tx2, ty2, lasty, idx; int que[60], head_, tail, h, stp[60]; struct graph {int head[60], to[3600], next[3600], lb;void clear(void) {memset(head, -1, sizeof head);memset(next, -1, sizeof next);lb = 0;}void ist(int aa, int ss) {to[lb] = ss;next[lb] = head[aa];head[aa] = lb;++lb;} } g;int main(void) {freopen("jumping.in", "r", stdin);freopen("jumping.out", "w", stdout);scanf("%d", &TT);while (TT--) {memset(x, 0, sizeof x);memset(y, 0, sizeof y);memset(que, 0, sizeof que);memset(stp, -1, sizeof stp);head_ = tail = 0;scanf("%d", &n);lasty = -2147483637;idx = 0;for (int i = 0; i < n; ++i) {scanf("%d%d", &tx1, &ty1);if (tx1 != lasty + 1) {x[idx] = lasty + 1;y[idx] = tx1 - 1;++idx;}lasty = ty1;}x[idx] = lasty + 1;y[idx] = 2147483637;T = idx << 1 | 1;++idx;scanf("%d", &lj);if (lj & 1 ^ 1) {puts("-1");continue;}g.clear();for (int i = 0; i < (idx << 1); i += 2) {tx1 = x[i >> 1] + (x[i >> 1] & 1? 1: 0);ty1 = y[i >> 1] - (y[i >> 1] & 1? 1: 0);for (int j = 1; j < (idx << 1); j += 2) {tx2 = x[j >> 1] + (x[j >> 1] & 1? 0: 1);ty2 = y[j >> 1] - (y[j >> 1] & 1? 0: 1);if (tx1 + lj <= ty2 && ty1 + lj >= tx2 || tx1 - lj <= ty2 && ty1 - lj >= tx2) {g.ist(i, j);}}}for (int i = 1; i < (idx << 1); i += 2) {tx1 = x[i >> 1] + (x[i >> 1] & 1? 0: 1);ty1 = y[i >> 1] - (y[i >> 1] & 1? 0: 1);for (int j = 0; j < (idx << 1); j += 2) {tx2 = x[j >> 1] + (x[j >> 1] & 1? 1: 0);ty2 = y[j >> 1] - (y[j >> 1] & 1? 1: 0);if (tx1 + lj <= ty2 && ty1 + lj >= tx2 || tx1 - lj <= ty2 && ty1 - lj >= tx2) {g.ist(i, j);}}}que[tail++] = 0;stp[0] = 0;while (head_ != tail) {h = que[head_++];for (int j = g.head[h]; j != -1; j = g.next[j]) {if (stp[g.to[j]] == -1) {stp[g.to[j]] = stp[h] + 1;que[tail++] = g.to[j];}}}printf("%d\n", stp[T]);}return 0; }
轉載于:https://www.cnblogs.com/ciao-sora/p/6002862.html
總結
以上是生活随笔為你收集整理的[ZPG TEST 109] 兔子跳跃【构图】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【JavaEE】WebService到底
- 下一篇: javascript焦点图(根据图片下方