"Help Jimmy" 是在下圖所示的場景上完成的遊戲。 ios
場景中包括多個長度和高度各不相同的平臺。地面是最低的平臺,高度爲零,長度無限。
Jimmy老鼠在時刻0從高於全部平臺的某處開始下落,它的下落速度始終爲1米/秒。當Jimmy落到某個平臺上時,遊戲者選擇讓它向左仍是向右跑,它跑動的速度也是1米/秒。當Jimmy跑到平臺的邊緣時,開始繼續下落。Jimmy每次下落的高度不能超過MAX米,否則就會摔死,遊戲也會結束。
設計一個程序,計算Jimmy到底地面時可能的最先時間。 函數
1 3 8 17 20 0 10 8 0 10 13 4 14 3Sample Output
23
題解:
1.首先Jimmy是從高向低掉落,因此首先你須要將輸入的板塊按照高度的順序由高到低排列,並且與其相對應的左右橫座標也須要更新
2.排序以後,思考Jimmy的位置,一開始,它的位置是一個點,那麼他只能夠垂直向下掉落,並且只有倆種狀況
(1)直接落地(前提是這個高度要小於MAX, 否則它就摔死了)
(2)掉落到第一塊板子上
3.要注意,板塊不能夠穿越!並且有一種邊緣狀況,就是你從上一塊板塊的邊緣落下,正好落到了下一塊的板塊的邊緣,它是能夠停留的(就像以前手機上玩的遊戲跳跳球同樣)
4.從新回到Jimmy落到了一塊板塊的中央,這是先無論它, 你只須要知道它落到了哪一個板塊上, 並把它存儲起來
5.這時咱們從第一個板塊提及,也就是最高的那個板塊,咱們來討論從它的邊緣下落問題,能夠分爲倆個問題, 從左邊緣下落, 右邊緣下落
因而能夠獲得(以左邊緣下落爲例子,右邊緣相同)
if(板子k左端正下方沒有別的板子){
if(板子k的高度h(k)大於MAX)
LeftMinTime(k) = INF(很大的數)
else
LeftMinTime(k) = h(k);
}
else if(板子k左端正下方的板子編號時m)//這裏須要注意,僅當倆塊板子的高度差小於MAX才能執行下面的語句,不然Jimmy會被摔死,則Time爲INF(很是重要)
LeftMinTime(k) = h(k) - h(m) + Min(LeftMinTime(m) + Lx(k) - Lx(m), RightMinTime(m) + Rx(m) - Lx(k));
}
6.對於尋找下方是否有板子能夠設置一個函數find
int find(int x, int h) {//x爲Jimmy所在的橫座標,h爲當前板子的高度
for (int i = 0; i < N; i++) {
if (x >= X1[i] && x <= X2[i]) {
if (h > H[i] && H[i] != 0)//這裏要保證H[i]不爲0,由於地面是0,樹立在地面的板子是沒有意義的
return i;
}
}
return -1;
}
測試數據
2 3 8 7 2 6 14 6 4 10 4 5 14 2 1 6 10 20 2 3 5 answer: 17 10 1 4 14 5 6 3 22 1 16 23 2 16 30 3 13 21 4 答案:15 1 2 2 12 8 0 10 10 2 12 5 答案:22 1 3 8 17 20 8 10 8 8 10 13 8 14 3 ans:17 1 60 822 302 50 813 823 298 813 823 293 816 826 213 816 826 178 817 827 218 813 823 148 821 831 73 814 824 248 813 823 283 815 825 158 819 829 58 814 824 13 813 823 28 819 829 233 814 824 43 773 783 293 821 831 93 818 828 268 816 826 198 818 828 113 814 824 208 816 826 68 821 831 133 794 804 248 814 824 108 829 839 28 818 828 143 844 854 298 802 812 133 801 811 28 818 828 238 817 827 8 816 826 48 820 830 3 819 829 288 822 832 138 820 830 183 855 865 13 777 787 268 820 830 63 789 799 28 822 832 33 855 865 213 779 789 208 836 846 248 806 816 33 821 831 263 818 828 83 846 856 263 789 799 68 854 864 8 854 864 283 801 811 298 805 815 143 822 832 23 821 831 173 813 823 153 858 868 138 818 828 98 839 849 133 答案:352
代碼 :
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 6 static const int MAXLEN = 1010; 7 8 #define INF 1e9; 9 10 int t, N, X, Y, MAX; 11 int X1[MAXLEN] = { 0 }, X2[MAXLEN] = { 0 }, H[MAXLEN] = { 0 }, LeftMinTime[MAXLEN] = { 0 }, RightMinTime[MAXLEN] = { 0 }; 12 13 void h_sort(int X1[], int X2[], int H[]) { 14 for (int i = 0; i < N; i++) { 15 for (int j = i + 1; j < N; j++) { 16 if (H[j] > H[i]) { 17 int temp; 18 temp = H[i]; 19 H[i] = H[j]; 20 H[j] = temp; 21 temp = X1[i]; 22 X1[i] = X1[j]; 23 X1[j] = temp; 24 temp = X2[i]; 25 X2[i] = X2[j]; 26 X2[j] = temp; 27 } 28 } 29 } 30 } 31 32 int find(int x, int h) { 33 for (int i = 0; i < N; i++) { 34 if (x >= X1[i] && x <= X2[i]) { 35 if (h > H[i] && H[i] != 0) 36 return i; 37 } 38 } 39 return -1; 40 } 41 42 int main() { 43 cin >> t; 44 while (t--) { 45 memset(X1, 0, sizeof(X1)); 46 memset(X2, 0, sizeof(X2)); 47 memset(H, 0, sizeof(H)); 48 memset(LeftMinTime, 0, sizeof(LeftMinTime)); 49 memset(RightMinTime, 0, sizeof(RightMinTime)); 50 cin >> N >> X >> Y >> MAX; 51 for (int i = 0; i < N; i++) 52 cin >> X1[i] >> X2[i] >> H[i]; 53 54 //排序 55 h_sort(X1, X2, H); 56 //第一塊板子 57 int key = find(X, Y); 58 59 if (key == -1) { 60 cout << Y << endl; 61 continue; 62 } 63 64 for (int i = N - 1; i >= 0; i--) { 65 int m = find(X1[i], H[i]); 66 if (m == -1) { 67 if (H[i] > MAX) { 68 LeftMinTime[i] = INF; 69 } 70 else { 71 LeftMinTime[i] = H[i]; 72 } 73 } 74 else { 75 if(H[i] - H[m] <= MAX) 76 LeftMinTime[i] = H[i] - H[m] + min(LeftMinTime[m] + X1[i] - X1[m], RightMinTime[m] + X2[m] - X1[i]); 77 else 78 LeftMinTime[i] = INF; 79 } 80 int r = find(X2[i], H[i]); 81 if (r == -1) { 82 if (H[i] > MAX) { 83 RightMinTime[i] = INF; 84 } 85 else { 86 RightMinTime[i] = H[i]; 87 } 88 } 89 else { 90 if(H[i] - H[r] <= MAX) 91 RightMinTime[i] = H[i] - H[r] + min(LeftMinTime[r] + X2[i] - X1[r], RightMinTime[r] + X2[r] - X2[i]); 92 else 93 RightMinTime[i] = INF; 94 } 95 } 96 int minTime = Y - H[key] + min(LeftMinTime[key] + X - X1[key], RightMinTime[key] + X2[key] - X); 97 cout << minTime << endl;; 98 } 99 return 0; 100 }