AtCoder Regular Contest 061 + AtCoder Beginner Contest 045
成績
ARC参加で354位。なかなか緑にはならない。
解法メモ
A問題
台形の面積は 。
B問題
3人の手札と捨てられたカードの文字を変数に持たせて、実際にシミュレートすればよい。3人で最大300枚しかカードを持っていないのですぐに終わる。
C問題
結局のところ、与えられた数字列をバラバラに分解して、数字と数字の間に順番に+を入れたり入れなかったりしていけばよい。
ビット演算をつかえば効率が良い。最大で10文字しかないので、使うビットも最大9個だから十分。
D問題
C++とかならばmapを使えば一発らしいが、あいにくC言語にそういうのは用意されていない。
黒マスは最大で 個しかないから、与えられた黒マスに対して、そのマスによって黒マスの数が変化するような3行3列のマスを列挙していけばよい(最大 )。3行3列のマスが識別できればよいから、どこか1つのマス(例えば左上)を代表として表すことにすればよい。
列挙したマスを上・左からの昇順でソートすると、それぞれの3行3列マスには出現した回数だけ黒マスがあることになる。
列挙したマスを順番に見ていって、1~9個あるマスの個数を数え、最後にその総和 を計算しておけば、黒マスのない3行3列マスは 個あることがわかる。
わかってしまえばあっという間なのにわからなかったのが悔しい。
E問題
二部グラフを使えばよいらしい。まだわかっていない。
F問題
捨てられたカードを順番に見ていくことにする。たとえば、abcbacaa とカードが捨てられてゲームが終わったとする。
- ゲームが終わったときにAのターンだから、Aが勝ったことになる。すなわち、Aが勝つためには最後に捨てられたカードが a でなくてはならない。
- Aのターンでゲームが始まって、Aのターンでゲームが終わったから、Aは最初カードを4枚 (abca) 持っていたことになる。これは、a が書かれた捨てられたカードの枚数と一致する。
- Bは先頭から ca 、Cは先頭から ba というカードを順に持っていたことがわかる。これも、b, c が書かれた捨てられたカードの枚数に一致する。
以上のことから捨てられるカードの順列は、最後に a が来るような、 個の a、 個以下の b、 個以下の c の並べ方の総数に帰着する。
いま、 ターン目にAが最後に a のカードを捨てて勝ったとする。
並べる b の個数を 、c の個数を とおくと、Bの持つ 枚の手札とCの持つ 枚の手札はどの文字が書いてあってもよい。すなわち、カードの組み合わせは 通り。
だから、。
ターン目までに捨てられた 枚のカードのうち、a のカードが 枚、残る 枚が b, c のカードである。この組み合わせの数は、
通り。
したがって、求める数は
を で割ったあまり。
二項係数を求めるところは、フェルマーの小定理を使って、 と ()を事前に求めておく。
部分点解法
愚直に二項係数の総和を求めると時間を食うので、部分点しかとれない。
満点解法
二項係数 () の総和は である(二項定理)。このことを利用して、二項係数の和を一気に求める。
図の破線で囲まれた部分の二項係数の和を求めてみよう。
- 1段目の和は1。
- 2段目の和は、1段目の1が2回現れるので1段目の2倍で2。
- 3段目の和は、2段目の2つの1がそれぞれ2回ずつ現れるので、2段目の2倍で4。
- 4段目の和は、3段目の3つの数がそれぞれ2回ずつ現れるので、3段目の2倍で8。
- 5段目の和は、4段目の左端を除く3つの数がそれぞれ2回ずつ現れ、左端のみ1回現れるので、4段目の2倍から4段目の左端を引いて15。
- 6段目の和は、5段目の両端を除く2つの数がそれぞれ2回ずつ現れ、両端はそれぞれ1回現れるので、5段目の2倍から5段目の両端を引いて25。
- 7段目の和は、6段目の中央の数が2回ずつ現れ、両端はそれぞれ1回現れるので、6段目の2倍から6段目の両端を引いて35。
- 8段目の和は、7段目の2つの数がそれぞれ1回ずつ現れるので、7段目の2倍から7段目の両端を引いて35。
以上のことから、
- 1段目の和は1。
- 段目の和は、 段目の和の2倍から、追加しない側の 段目の端の数を引いたもの。
というようにして高速に求めることができる。