阿茂這週假日要去學校和同學一起練習躲避球比賽。躲避球的目標為擲球攻擊對方內場球員,在內場的球員在對方的球來時可以選擇躲開或是接住球,如果擊中身體且沒人接住,則該名球員需移至外場等待。
阿茂在練習躲避球時給自己訂了一個策略:
- 原地不動:若落球位置不在阿茂可接球的範圍內則他不會移動。
- 接球:若落球位置在可接球範圍且球速夠慢,阿茂會移動到球的位置且接住球。
- 閃躲:若落球位置在可接球範圍但球速過快,則阿茂會選擇向球的反方向 (球在阿茂左邊,阿茂就往右邊移動) 移動 15 單位距離;若落球位置與阿茂位置剛好相同,他會往左邊方向閃躲。
假設阿茂在位置 100,接球的左右延伸長度為 10 (即 [100–10, 100+100] = [90, 110] 為接球範圍),可接球的球速上限為 10。若落球位置為 99 且球速為 5,則阿茂會選擇接住球且站在位置 99;但若落球位置為 99 且球速為 20,則阿茂會閃躲到 115 (100 + 15) 的位置。
請你利用程式計算阿茂在經過一連串躲避球練習後站著的位置。
範例測資
範例輸入 | 範例輸出 |
---|---|
輸入第一列有兩個整數 X、R、V (0 ≤ X ≤ 1000,0 ≤ R ≤ 500,1 ≤ V ≤ 50),分別表示阿茂的位置、接球的左右延伸長度和可接球的球速上限。 第二列有一個整數 N (1 ≤ N ≤ 100) 表示練習的次數,之後有 N 列,每一列有兩個整數 P 和 S (0 ≤ P ≤ 1000,0 ≤ S ≤ 50) 表示每一次的落球位置和球速。同一列任兩個整數間以空白間隔。 | 輸出一個整數表示最後阿茂所在位置。 |
100 10 10 3 99 5 97 3 88 4 | 88 |
500 80 15 5 400 10 420 5 300 20 395 25 435 18 | 420 |
20 10 5 3 30 8 15 2 20 10 | 0 |
解題思路
每次紀錄新的 P 和 S 時,先宣告兩個變數 left 和 right,分別代表目前可以接球的左右邊界。
如果今天 P 沒有在 left 和 right 的範圍內,則不需要做任何動作。
如果今天 P 在範圍內,則要先判斷球速 S 是否超過可以承受的球速 V。如果 S <= V,代表可以接球,所以將 X 設定成 P。如果球速過快,則要判斷要往哪邊閃躲,如果今天 P >= X,代表球在右邊,所以要往左閃 X -= 15,這邊使用 >= 是因為題目有說如果 P == X 要往左閃,如果今天球在左邊就是往右閃 X += 15。
最後輸出 X 即可。
範例程式碼-ZeroJudge H660: 躲避球 (DodgeBall)
#include <iostream>
using namespace std;
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
int X, R, V, N;
cin >> X >> R >> V >> N;
for (int i = 0; i<N; i++) {
int P, S, left = X - R, right = X + R;
cin >> P >> S;
if (P < left || P > right) continue;
if (S <= V) {
X = P;
continue;
}
if (P >= X) X -= 15;
else X += 15;
}
cout << X << "\n";
}
//ZeroJudge H660
//Dr. SeanXD