# Geometry# Simulation# Math

f646 - 小球碰撞

🔗 前往 ZeroJudge 原題

題目描述

題目描述了一個小球在 H x W 的矩形區域內以 45 度角運動,並與牆壁碰撞反彈的情況。給定時間 T,需要計算小球在 T 時間後的座標 (X, Y)。小球從左上角 (0, 0) 開始,以 45 度角向右下運動。

解題思路

小球以 45 度角運動,因此其水平和垂直方向的速度相等。我們可以通過計算小球在水平和垂直方向上移動的距離來確定其最終位置。由於小球會與牆壁碰撞並反彈,因此需要考慮小球在水平和垂直方向上移動的次數。

我們可以通過 T % WT % H 來計算小球在水平和垂直方向上移動的距離。如果 T % WT % H 為 0,則表示小球沒有碰撞牆壁,否則表示小球碰撞了牆壁。如果小球碰撞了牆壁,則需要將其位置調整到牆壁的另一側。

具體來說,如果 T / W & 1 為 1,則表示小球在水平方向上碰撞了奇數次牆壁,因此其最終位置為 W - T % W。否則,其最終位置為 T % W。同樣,如果 T / H & 1 為 1,則表示小球在垂直方向上碰撞了奇數次牆壁,因此其最終位置為 H - T % H。否則,其最終位置為 T % H

由於小球以 45 度角運動,因此其水平和垂直方向上的速度為 sqrt(2) / 2。因此,小球的最終位置為 ((T / W & 1) ? W - T % W : T % W) * unitL((T / H & 1) ? H - T % H : T % H) * unitL,其中 unitL = sqrt(2) / 2

複雜度分析

  • 時間複雜度: O(1)
  • 空間複雜度: O(1)

程式碼

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
	cin.sync_with_stdio(0); cin.tie(0);
	int T, H, W;
	double unitL = sqrt(2) / 2;
	while (cin >> T >> H >> W) 
		cout << fixed << setprecision(1) << "x=" << ((T / W & 1) ? W - T % W : T % W) * unitL << ' ' << "y=" << ((T / H & 1) ? H - T % H : T % H) * unitL << '\n';
}

Discussion