こんにちは、ナナオです。
前回に引き続き競プロを実施していきたいと思います。
今回の問題は以下です。
実装
まずは単純に考えてみます。
まず条件のひとつ目として、時間内に移動できる距離は時間内に収まっている必要があります。
移動距離は「移動前のx座標と移動後のx座標の差」と「移動前のy座標と移動後のy座標の差」を足し合わせれば計算できます。
この「移動距離」が「移動前の時間と移動後の時間の差」の中に収まっているかどうかを判定する必要があります。
次に条件の二つ目として、先ほどの「移動距離」と「移動前の時間と移動後の時間の差」の奇数偶数判定が一致している必要があります。
これは単純で、例えば以下のようなケースを考えてみます。
2
1 1 0
3 1 0
このケースでは時間が1のときと時間が3のときの場所が全く同じです。
この場合条件の一つ目は満たしていますが、動き方としてはどうなるでしょうか?
…一回違う場所に行って戻ればこの動きは実現しそうですね。
ということは、条件1を満たしている場合で時間に余りがある場合は「行って」「戻る」という挙動ができるのであればよさそうですね。
さて、論よりコードということで以下のように実装しました。
use proconio::input;
fn main() {
input! {
n: usize,
data: [(i16, i16, i16); n],
};
let (mut c, mut sy, mut sx) = (0, 0, 0);
for i in 0..n {
let (t, x, y) = data[i];
let dd = (x - sx).abs() + (y - sy).abs();
let dt = t - c;
if dd > dt || dt % 2 != dd % 2 {
println!("No");
return;
}
sy = y;
sx = x;
c = t;
}
println!("Yes");
}
これだとうまく通りませんでした。なんだかまた値のオーバーフローが起こってしまったようなので、dataの値定義を変更しました。
use proconio::input;
fn main() {
input! {
n: usize,
data: [(i32, i32, i32); n],
};
let (mut c, mut sy, mut sx) = (0, 0, 0);
for i in 0..n {
let (t, x, y) = data[i];
let dd = (x - sx).abs() + (y - sy).abs();
let dt = t - c;
if dd > dt || dt % 2 != dd % 2 {
println!("No");
return;
}
sy = y;
sx = x;
c = t;
}
println!("Yes");
}
これで動きました。
ということで今回はこれで👍