【シミュレーション 4】位置情報システム (paizaランク B 相当)
解答例
問題文に沿って実装します。
等速直線運動の計算は以下の通りです。
移動元が、時刻 t_1 で座標 (y_1,X_1),
移動先が、時刻 t_2 で座標 (y_2,X_2) であるような
2 点の間を等速直線運動すると仮定したとき、
移動元と移動先の間、時刻 t_1 ≦ T ≦ t_2 における y 座標は、
移動元y_1 に、
等速直線運動の単位時間あたりに進む距離 (y_2-y_1)/(t_2-t_1) と
移動時間 (T-t_1) をかけた値を
足すといった計算をすればよいので、
移動元y座標 + 移動時間 * 単位時間あたりに進む距離、すなわち、
y_1 + (T-t_1)*(y_2-y_1)/(t_2-t_1) となります。
x座標についても同様です。
最後に、小数点以下を切り捨てます。
解答例(C++の場合参考)
JavaScriptの計算で、 Number型 は小数点以下約 17 桁の精度しか保持できません。BigInt型で計算します。
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
const [n] = lines[0].split(" ").map(Number);
//1.時刻 t_1(=0), t_2, ... , t_n(=100) のユーザーの位置情報 (y,x) を取得する。
const [t, y, x] = [[], [], []];
for (let i = 0; i < n; i++) {
[t[i], y[i], x[i]] = lines[i + 1].split(" ").map(Number);
}
//2.各時刻 T = 0, 1, ..., 100 のユーザーの座標(位置情報)を次の方法で計算する。
let now = 0;//配列t,y,xで、今見ているインデックス
for (let T = 0; T <= 100; T++) {
//1.T = t_1, T = t_2, ..., T = t_n のいずれかに当たる場合
if (T === t[now]) {
//時刻 T における座標(1. で取得した位置情報)を時刻 T における座標 (y,x) とする。
console.log(y[now], x[now]);
now++;//次へ
//2.t_i < T < t_{i+1} (1 ≦ i < n) の場合
} else {
/*t_i 時点での座標 (y_i, x_i) から t_{i+1} 時点での座標 (y_{i+1}, x_{i+1}) へ
等速で直線移動すると仮定し、時刻 T における座標を計算によって求める。*/
console.log(
Math.trunc(Number(BigInt(y[now - 1]) + BigInt((T - t[now - 1])) * BigInt((y[now] - y[now - 1])) / BigInt((t[now] - t[now - 1])))),
Math.trunc(Number(BigInt(x[now - 1]) + BigInt((T - t[now - 1])) * BigInt((x[now] - x[now - 1])) / BigInt((t[now] - t[now - 1]))))
);
}
}