PKU 1012 「Joseph」
情報 
注目度
2
閲覧数
1466
解決済
暇なときに
このエントリーをはてなブックマークに追加
watanabe
(17pt)
PKUのNo.1012の解き方が分かりません。どなたか分かる方がいたら、教えてください。

問題URL
http://acm.pku.edu.cn/JudgeOnline/problem?id=1012
2010-06-13 23:18:26
natrium
(84pt)
1~13のkについて、mの値を1ずつ大きくして条件を満たす最低のmをそれぞれ求めて配列に格納すれば良いと思います。
(最初に一括で計算せずに、毎度入力の度に計算するとTLEになってしまいます。)

ここで、「あるkとmが与えられたときに、それらは問題の条件を満たすか」という問題に帰着したわけですが、
それは普通にシミュレーションすれば求まると思います。
パラメータとして、現在の人数nと最後に死刑を執行された人のid(0~2*k-1) posを用意します。
nの初期値は2*kで、posの初期値は-1です。
(posの初期値が-1なのは、一番最初だけi番目の場所を「i+1」として考えるためです。一番最初は、2*k-1番目の人の所に立っていてそこからm回回るのと同義なので。)
そして、posにmを足して現在の人数nで割った余りを代入します。(この人が次の死刑囚)
このposがkより小さければ、その人は善人となりますからこのk, mの組合せでは条件を満たさないということになりますので、シミュレーションを終了します。
そうでなければ全体の人数が1少なくなるので、posとnを1ずつ減らします。
これをnがk以下になるまで続けることができればそのk, mの組合せで条件を満たすということになります。

一応これで十分なのですが、探索するmの値はもう少し枝刈りすることが出来ます。
まず、最初の状態で必ず悪人に止まらなければならない⇔mを2*kで割った余りが0かkより大きい
という条件をつけることが出来ます。
次に、一番最後の一歩手前、悪人が残り1人となっている場合を考えます。
ここまでシミュレーションがつづいていると言うことは、当然、k-1人目に処刑した人も悪人ですから、最後に処刑する悪人と、k-1人目に処刑した悪人は悪人が2人残っている状態では必ず隣り合っていることになります。
この2人の悪人は、それぞれidがkとk+1となっています。
このとき、m, kの組合せが条件を満たすとするならば、「kがk-1人目, k+1がk番目に処刑される」か「k+1がk-1人目、kがk番目に処刑される」のどちらかとなります。
少し考えれば、前者の場合はmをk+1で割った余りが1でなければならないし、後者のばあいはmをk+1で割った余りが0でなければならないと言うことが分かると思います。
従って、更に探索するmの値を減らすことが出来ます。
この2点を実装すれば愚直な実装の5倍ほどの実行速度がでると思います。

最後に、自分が通したソースコード(C++)を貼っておきます。
http://gist.github.com/437561
2拍手 |
2010-06-14 20:17:57
一言投稿 (Q&Aに関して、思ったことなどをつぶやいてみよう!)
一言投稿はまだありません

そのままでしばらくお待ちください


しばらくたっても変わらない場合はキャンセルしてください

キャンセル

以下の内容で回答を投稿します

よろしいですか?

回答内容

回答の投稿が完了しました

こちらからご確認ください