みんなのプロコン 2019の参加記録.
B - Path
4つの街と3つの道が与えられる. 一筆書で全ての街を訪れることができるか.
制約
同じ街の対の間を結ぶ道は複数存在しない どの2つの街の間も、道を何本か通ることで行き来することができる
より, 全ての街を訪れることは可能であることがわかる. このとき道と街の組み合わせしてありうるのは以下の2パターン.
A
B
一筆書き出来るのはB.
Aは1つの街から3本以上の道が存在する場合なので, 街から生えている道の本数で判定すればいい.
解答
use std::io;
fn main() {
let mut a = 0;
let mut b = 0;
let mut c = 0;
let mut d = 0;
for _ in 0..3 {
let ab = read::<usize>();
for i in ab {
match i {
1 => a += 1,
2 => b += 1,
3 => c += 1,
4 => d += 1,
_ => unreachable!(),
}
}
}
if a > 2 || b > 2 || c > 2 || d > 2 {
println!("NO");
} else {
println!("YES");
}
}
C - When I hit my pocket...
手持ちのビスケット1枚, 0円の状態から
- 持っているビスケットを増やす
- ビスケット1枚をA円に交換
- 1円をビスケットB枚の交換
以上の操作を好きな順に回行ってビスケットの枚数を最大化する. なお虚無からビスケットを生成できるらしい.
ビスケット → 円 → ビスケットの両替には2ターン消費するので, 2枚以上の利益がなければ愚直にビスケットを増やすのと変わらない.
なので の場合にはビスケットを増やす操作だけ行うのが最善.
の場合には, ビスケット→ 円→ ビスケット の操作でビスケットを枚増産できる. 最終的に円を持っていても意味がないので, この一連の操作は操作は同じ回数行いたい.
簡単のために, ビスケットを0枚もっている状態から回の操作を行えるとする.
アプローチとしては,
- A枚たまるまでビスケットを増やす
- 残り回の操作で両替を繰り返す
手順2は回行うことができる. 偶奇によっては操作回数が一回あまるが, ここでビスケット→ 円の両替をしても仕方がないのでビスケットを1枚増やす.
解答
use std::io;
fn main() {
let (k, a, b) = {
let i = read::<u64>();
(i[0], i[1], i[2])
};
if a >= b || b - a <= 1{
println!("{}", k + 1);
return;
}
let ans: u64 = if (k + 1 - a) % 2 == 0 {
(b - a) * (k + 1 - a) / 2 + a
} else {
(b - a) * (k - a) / 2 + a + 1
};
println!("{}", ans);
}
所感
考察を詰めきらずにふわふわした状態でB,Cをときがち. 論文が一段落したので, しばらくはこれを書いてから実装するくらいの気持ちで精進してみる.
Comments