TopCoder SRM 598 Div1 Medium FoxAndFencing
問題
FoxとLissがゲームをする。Foxが先手でLissが後手である。
数直線上の格子点を二人が動く。最初Foxは0の点にいて、Lissはdの点にいる。
Foxはmov1以下の整数の距離を左右どちらにも動けて、その後でrng1以下の距離にいる相手を攻撃できる。
Lissはmov2以下の整数の距離を左右どちらにも動けて、その後でrng2以下の距離にいる相手を攻撃できる。
先に相手を攻撃したほうが勝ちである。
お互いが最善を尽くしたとき、どちらが勝つかあるいは引き分けかを答えよ。
制約条件
変数は全部10^8以下
方針
初手で攻撃できたらFoxの勝ち。
そうじゃないとき、初手で相手の攻撃範囲から逃げられなかったらFoxの負け。
そうじゃないとき、mov1 = mov2だったら引き分け。
mov1>mov2のとき、Foxは相手の攻撃範囲(rng2 + mov2)ギリギリに近づいて、相手がmov2逃げて、なおかつ攻撃できたら勝ちだから、
rng2 + 2*mov2 ≦ rng1 + mov1なら勝ち。そうでないなら引き分け。
逆もFoxとLissが入れ替わって同じことになる。それだけの問題……
ソースコード
const string Ciel = "Ciel"; const string Liss = "Liss"; const string Draw = "Draw"; class FoxAndFencing { public: string WhoCanWin(int mov1, int mov2, int rng1, int rng2, int d) { if(d <= mov1 + rng1) return Ciel; if(d + mov1 <= mov2 + rng2) return Liss; if(mov1 == mov2){ return Draw; } if(mov1 > mov2){ if(rng1 + mov1 > rng2 + 2 * mov2) return Ciel; return Draw; } if(rng1 + 2 * mov1 < rng2 + mov2) return Liss; return Draw; } };