TopCoder Open Round #1
懇親会が終わって家に帰ってきた後、しばらくだらーっとして時間を潰した。そして26:00から、TopCoder OpenのRound #1。このラウンドで400/700に絞られる。
とりあえずRegistrationだけすればTCOのTシャツがもらえるのでそれだけでちょっと満足。
しかしやっぱ、一日のうちに二回コンテストをやって、しかも二回目が午前2時からっていうのはきついなぁ...
今回の問題は3問。途中で配点ミスが見つかって、1問目と2問目の難易度が入れ替わったり、時間が30分くらい伸びたり、なんか色々とアクシデントがあった模様。とりあえず問題を紹介してみる。
問題1 (350pt.)
無向グラフの隣接行列が与えられるので、最大マッチングを求めよ。以上。
ただし、ノード数は最大18。
問題2 (500pt.)
最上位の桁の数を最下位の桁にくっつけることを、数を''rotate''することと定義する。つまり、下のような操作がrotate。
12345 -> 51234
102564 -> 025641
分数p/qが与えられるので、rotate操作をしたときに数がp/q倍になるような最小の自然数を求める問題。たとえば、例の2番目はp=1, q=4の時の解。ただし、rotate前の数の最上位桁は0であってはならない。rotate後の最上位桁が0であっても構わない。2000000000(2*10^9)未満にそのような数が無ければ-1を返す。 。
問題3 (900pt.)
n個の要素をもつ集合 に対して、全単射 を''permutation''と呼ぶことにする。たとえば、 はpermutationのひとつ。また、''identity permutation''とは全ての要素を同じ要素に射影するpermutationのこと。つまり、 。
ここで、 に対する permutation の''order''を、 を満たす最小のkと定義する。たとえば、Aのorderは2。
整数n ( )が与えられるので、 に対する異なるorderのpermutationがいくつ存在するかを返す。たとえば、 に対するpermutationにはorderが1,2,3のものが存在するので、n=3に対する解答は3。
さて、ぼくはどうだったかというと。
問題2
最初はこれが一番点数の低い問題と表示されていたのでこの問題から始めた。
rotate前の数を (ただし )とすると、rotate後の数は なので、それが 倍になるとき、 。n, kの小さい順にxを計算して、そのような整数xが存在するかチェックしてやればいい。
注意すべきはの時の処理と、xの範囲が でなければならないことと、分母が0のときの処理。ぼくは後者二つを忘れていて撃墜タイムに落とされた。
問題1
一般のグラフのマッチングなんてわかんないよー、全探索するか? と最初は思ったけど、ノード数が18と少ないので、ノードの部分集合に関する完全マッチングがあるかどうかをDPで求めて、完全マッチングが存在するような部分集合の大きさの最大値を返せばいい。これは通った。
問題3
なんとなくDPっぽいんだけど、よくわからず。
あるpermutationのorderは、各巡回要素(?)の大きさのlcmで求められることはわかったんだけど、それをどうやって使うといいのかわからなかった。