<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-15880554</id><updated>2011-12-29T08:41:35.218+09:00</updated><category term='blogger'/><category term='topcoder'/><category term='java'/><category term='python'/><category term='google code jam'/><title type='text'>4 TopCoder</title><subtitle type='html'>Love solving problems? Here's your chance to prove it.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://4topcoder.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>hayato</name><uri>http://www.blogger.com/profile/15567939639489772436</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>50</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15880554.post-8305408759461834920</id><published>2009-01-07T01:14:00.005+09:00</published><updated>2009-01-07T01:53:33.939+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM432</title><content type='html'>SRM432に挑戦。前回から6ヶ月以上たってるよ。6ヶ月以上、参戦してないと、ランキングから除外されるんですねー。
今までは、ThinkPad + Linux (もち、Gentoo Linux) + Eclipse + Javaという環境でやってたんですが、ThinkPadが壊れてからは、なかなか環境を整えることをしないまま、時間がたってしまいました。

今回は、Macbook Pro + Eclipse + Javaという環境で、久しぶりに参戦してみました。レーティングが下がるフラグがたちまくりの状態だったんですが、
結果は、250 Passed, 500 Passed, 4 successful challengesで、レーティングは2121 -&gt; 2220と上昇。ようやくRedになりました。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-8305408759461834920?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/8305408759461834920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/8305408759461834920'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2009/01/srm432.html' title='SRM432'/><author><name>hayato</name><uri>http://www.blogger.com/profile/15567939639489772436</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-9137653353595335435</id><published>2008-06-15T04:02:00.001+09:00</published><updated>2008-06-15T04:09:46.353+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM405 - 5ヵ月ぶりの参戦</title><content type='html'>久しぶりのSRM。実に5ヶ月ぶりですよ。
C++にスイッチするはずが、手元の環境の問題で、やむなくJavaで参加してみる。

250はやるだけの問題。

500はいい解法がなかなか思いつかないまま、時間がなくなってきたので、
エレガントな解法はもうあきらめてBrute-force的に解いてみる。
コンテスト中は解法として正しいかどうか証明できなかったので、自信がなかったんですけど、
Passしました。ちょっと驚き。

レーティングは、2000 -&gt; 2121と上昇。
賞金つきマッチでしたので、おそらく賞金ももらえます。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-9137653353595335435?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/9137653353595335435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/9137653353595335435'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2008/06/srm405-5.html' title='SRM405 - 5ヵ月ぶりの参戦'/><author><name>hayato</name><uri>http://www.blogger.com/profile/15567939639489772436</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-4889348902124682115</id><published>2008-01-06T18:40:00.001+09:00</published><updated>2008-01-06T18:41:43.422+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM386</title><content type='html'>&lt;p&gt;2008年あけましておめでとう。今年最初のSRM、 &lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=11120"&gt;SRM386&lt;/a&gt; に挑戦。
今回も、ハード問題は解いた人が一人だけというスーパーハードでした。&lt;/p&gt;
&lt;table class="docutils" border="1"&gt;
&lt;caption&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=11120&amp;amp;rm=267996"&gt;Room Statistics&lt;/a&gt;&lt;/caption&gt;
&lt;colgroup&gt;&lt;/colgroup&gt;

&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Class Name&lt;/th&gt;
&lt;th class="head"&gt;Method Name&lt;/th&gt;
&lt;th class="head"&gt;Difficulty&lt;/th&gt;
&lt;th class="head"&gt;Coding Time&lt;/th&gt;
&lt;th class="head"&gt;Status&lt;/th&gt;
&lt;th class="head"&gt;Points&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=267996&amp;amp;rd=11120&amp;amp;pm=8444&amp;amp;cr=15632820"&gt;CandidateKeys&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;getKeys&lt;/td&gt;
&lt;td&gt;Level One&lt;/td&gt;
&lt;td&gt;0:15:25.443&lt;/td&gt;
&lt;td&gt;Passed System Test&lt;/td&gt;
&lt;td&gt;197.99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=267996&amp;amp;rd=11120&amp;amp;pm=8540&amp;amp;cr=15632820"&gt;PolygonCover&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;getArea&lt;/td&gt;
&lt;td&gt;Level Two&lt;/td&gt;
&lt;td&gt;0:22:50.327&lt;/td&gt;
&lt;td&gt;Passed System Test&lt;/td&gt;
&lt;td&gt;331.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=267996&amp;amp;rd=11120&amp;amp;pm=7953&amp;amp;cr=15632820"&gt;EscapeArtist&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;bestRoute&lt;/td&gt;
&lt;td&gt;Level Three&lt;/td&gt;
&lt;td&gt;0:24:44.715&lt;/td&gt;
&lt;td&gt;Opened&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;レーティングは、1918 -&amp;gt; 2009と上昇。
自己ベストは、2040ですので、あと一歩。
このあたりのレーティングだと、ハードが解けなくても、
コンスタントにEasyとMediumを解くことができれば、
大抵レーティングは上昇しますね。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-4889348902124682115?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/4889348902124682115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/4889348902124682115'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2008/01/srm386.html' title='SRM386'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-8114997635790420364</id><published>2007-12-28T03:13:00.001+09:00</published><updated>2007-12-28T03:22:38.005+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM385</title><content type='html'>&lt;p&gt;SRM385 に挑戦。今年、最後のSRMです。&lt;/p&gt;
&lt;p&gt;今回は、1100点問題は誰も解けないほどのハードな問題、
250点問題と500点問題はとっても素直な問題なんですけど、
500点問題はワーストケースのタイムアウトで落ちてしまいました。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
2.004s
&lt;/pre&gt;
&lt;p&gt;うーん。惜しい。0.004秒ほどオーバー。&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;メモするところで、HashMapではなく、普通に配列使っとく&lt;/li&gt;
&lt;li&gt;または、ゴールに達したらすぐ値を返す&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;でなんの問題なかったんですよね。
状態のサイズは、最大でも7 * 7 * 2^14 = 802,816 ですので、
HashMap使ってもまあ楽勝で2秒以内だろ。と勝手に思い込んだ、私の負けです。
ちゃんとTopCoderのシステム上で計測しとかないとだめですね。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-8114997635790420364?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/8114997635790420364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/8114997635790420364'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/12/srm385.html' title='SRM385'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-6005784468721432234</id><published>2007-12-27T01:53:00.002+09:00</published><updated>2009-01-07T10:27:29.139+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM384 - ゲーム</title><content type='html'>&lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=10808"&gt;SRM384&lt;/a&gt; に挑戦。結果は、以下の通り。&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=10808&amp;amp;rm=267772"&gt;Room Statistics&lt;/a&gt;&lt;/caption&gt;
&lt;colgroup&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Class Name&lt;/th&gt;
&lt;th class="head"&gt;Method Name&lt;/th&gt;
&lt;th class="head"&gt;Difficulty&lt;/th&gt;
&lt;th class="head"&gt;Coding Time&lt;/th&gt;
&lt;th class="head"&gt;Status&lt;/th&gt;
&lt;th class="head"&gt;Points&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=267772&amp;amp;rd=10808&amp;amp;pm=7659&amp;amp;cr=15632820"&gt;Library&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;documentAccess&lt;/td&gt;
&lt;td&gt;Level One&lt;/td&gt;
&lt;td&gt;0:06:01.087&lt;/td&gt;
&lt;td&gt;Passed System Test&lt;/td&gt;
&lt;td&gt;239.41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=267772&amp;amp;rd=10808&amp;amp;pm=7657&amp;amp;cr=15632820"&gt;SchoolTrip&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;duration&lt;/td&gt;
&lt;td&gt;Level Two&lt;/td&gt;
&lt;td&gt;0:51:13.541&lt;/td&gt;
&lt;td&gt;Passed System Test&lt;/td&gt;
&lt;td&gt;211.78&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=267772&amp;amp;rd=10808&amp;amp;pm=6866&amp;amp;cr=15632820"&gt;ChessTraining&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;game&lt;/td&gt;
&lt;td&gt;Level Three&lt;/td&gt;
&lt;td&gt;0:10:44.830&lt;/td&gt;
&lt;td&gt;Opened&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;今回は、500点問題は正確に確率を求めようとすると、かなり面倒くさいです。
何も考えずに、メモつき再帰などで計算しようとすると、
「あれ、元の状態に戻ってしまうよ。延々とループしてしまうよね。これ?どーしよ。。」
となってしまいます。
私は、これで30分くらい悩みました。&lt;/p&gt;
&lt;p&gt;うまく場合分けをすれば正確に求めることも可能ですが、
そうではなく、強引にシミュレーション(?)で求めてしまうって方法が、
一番楽だったようです。
ちなみに、このような強引に一定回数ループを回して計算する方法って、
なにか名前がついていないんですかね?
シミュレーションって言葉も、ちょっと正しくないような気もするんですけど。&lt;/p&gt;
&lt;p&gt;1000点問題は、ゲームの問題です。
ひとつひとつのゲームの結果を求めるのは簡単なんですが、
それが複数組み合わさるときの求めかたがわかりませんでした。
「なんらかの、Nimのようなゲームの考え方に落ち着くんだろうな。」とは思ってたんですけど。&lt;/p&gt;
&lt;p&gt;TopCoderのForumによりますと、このような複合ゲームの場合の考え方は、
以下の論文(TopCoderのメンバーである &lt;a class="reference" href="http://www.topcoder.com/tc?module=MemberProfile&amp;amp;cr=13396848"&gt;raso6sk&lt;/a&gt; の学士論文)が参考になります。&lt;/p&gt;
&lt;p&gt;&lt;a class="reference" href="http://www.fmph.uniba.sk/fileadmin/user_upload/editors/studium/svk/2007/INF/lenhardt.pdf"&gt;http://www.fmph.uniba.sk/fileadmin/user_upload/editors/studium/svk/2007/INF/lenhardt.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;しかし、この1000点問題を解いた人は、24人もいるんですよね。
みんな、よく知ってますね。さすが。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-6005784468721432234?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6005784468721432234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6005784468721432234'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/12/srm384.html' title='SRM384 - ゲーム'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-6638840212471756893</id><published>2007-10-02T23:39:00.001+09:00</published><updated>2007-10-03T21:39:10.975+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM368</title><content type='html'>&lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=10936"&gt;SRM368&lt;/a&gt; に挑戦。結果は以下の通り。&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=10936&amp;amp;rm=266460"&gt;Room Statistics&lt;/a&gt;&lt;/caption&gt;
&lt;colgroup&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Class Name&lt;/th&gt;
&lt;th class="head"&gt;Method Name&lt;/th&gt;
&lt;th class="head"&gt;Difficulty&lt;/th&gt;
&lt;th class="head"&gt;Coding Time&lt;/th&gt;
&lt;th class="head"&gt;Status&lt;/th&gt;
&lt;th class="head"&gt;Points&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=266460&amp;amp;rd=10936&amp;amp;pm=8245&amp;amp;cr=15632820"&gt;JumpingBoard&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;maxJumps&lt;/td&gt;
&lt;td&gt;Level One&lt;/td&gt;
&lt;td&gt;0:16:20.551&lt;/td&gt;
&lt;td&gt;Challenge Succeeded&lt;/td&gt;
&lt;td&gt;168.66&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=266460&amp;amp;rd=10936&amp;amp;pm=8249&amp;amp;cr=15632820"&gt;PolylineUnion&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;countComponents&lt;/td&gt;
&lt;td&gt;Level Two&lt;/td&gt;
&lt;td&gt;0:38:47.847&lt;/td&gt;
&lt;td&gt;Passed System Test&lt;/td&gt;
&lt;td&gt;245.21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=266460&amp;amp;rd=10936&amp;amp;pm=8247&amp;amp;cr=15632820"&gt;BinaryCodes&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ambiguous&lt;/td&gt;
&lt;td&gt;Level Three&lt;/td&gt;
&lt;td&gt;0:15:17.316&lt;/td&gt;
&lt;td&gt;Opened&lt;/td&gt;
&lt;td&gt;0.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="section"&gt;
&lt;h2&gt;JumpingBoard&lt;/h2&gt;
&lt;p&gt;これを、1). 普通にさくっと解くか、2). 解いたつもりで間違いに気付かず次の問題にいってしまうか、で落ち着きのある・なしが判定できますね。。&lt;/p&gt;
&lt;p&gt;まー、私は後者だったわけだが。多くの人がサイクルの判定で同じようなミスをしてました。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;PolylineUnion&lt;/h2&gt;
&lt;p&gt;500点問題。Geometry問題。
セグメントの交差判定が問題の中心。
最初は交点の座標を求めようとしたんですけど誤差の精度に確信が持てなかったので、
方針を変えて交差判定を整数のみを使用してがんばってみた。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;BinaryCodes&lt;/h2&gt;
&lt;p&gt;1000点問題。とても手が回らず。解けた人は一人だけというハードな問題でした。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;レーティングは、1760 &amp;gt; 1853と上昇。
Javaじゃなくて、C++にスイッチしようかなと思う、今日、このごろ。。&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-6638840212471756893?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6638840212471756893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6638840212471756893'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/10/srm368.html' title='SRM368'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-6791093376766405100</id><published>2007-09-18T22:35:00.001+09:00</published><updated>2007-09-20T20:02:11.654+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM366 - typo2連発</title><content type='html'>&lt;p&gt;久しぶりのSRM。 &lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=10781"&gt;SRM366&lt;/a&gt; に挑戦。&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7973&amp;amp;rd=10781"&gt;ChangingSounds&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=266307&amp;amp;rd=10781&amp;amp;pm=7973&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題。典型的DP。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7747&amp;amp;rd=10781"&gt;GuitarConcert&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=266307&amp;amp;rd=10781&amp;amp;pm=7747&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題。N=10なので、2^NのBrute-forceでいけます。
結果を、lexicographicallyで優先順位をつけるところだけが注意点です。&lt;/p&gt;
&lt;p&gt;ですが、System Testに落ちました。えーと、ここの、&lt;/p&gt;
&lt;pre class="literal-block"&gt;
void sort(String[] a, String[] b) {
    int N = a.length;
    for (int i = 0; i &amp;lt; N; i++) {
        for (int j = N-2; j &amp;gt;= i; j--) {
            if (a[j+1].compareTo(a[i]) &amp;lt; 0) {
                swap(a, j, j+1);
                swap(b, j, j+1);
            }
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;この行ですね。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
if (a[j+1].compareTo(a[i]) &amp;lt; 0) {
&lt;/pre&gt;
&lt;p&gt;iではなくjですよー。気付きましょうよー &amp;gt; 私。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
if (a[j+1].compareTo(a[j]) &amp;lt; 0) {
&lt;/pre&gt;
&lt;p&gt;これでSystem Testに通りました。
typoのままで、Example Caseに通ってしまったのが、運のつき。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7827&amp;amp;rd=10781"&gt;LateForConcert&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=266307&amp;amp;rd=10781&amp;amp;pm=7827&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;1000点問題にもかかわらず特に悩むところはない珍しく簡単な問題。
ですが、どうしても答えがあわない。。そのまま時間ぎれ。&lt;/p&gt;
&lt;p&gt;やはり、一箇所ミスってました。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
double[][][] next = new double[R][C][4];
fill(dp, INF);
&lt;/pre&gt;
&lt;p&gt;dpではなくnextですよー。気付きましょうよー &amp;gt; 私。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
double[][][] next = new double[R][C][4];
fill(next, INF);
&lt;/pre&gt;
&lt;p&gt;これでSystem Testに通りました。
typoというよりは、典型的なコピペ後の修正し忘れってやつですね。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=10781&amp;amp;rm=266307"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;今回は、3問全部解くべき簡単な問題セットだったと思うんですけど。
ミス2連発では、お話になりません。&lt;/p&gt;
&lt;p&gt;レーティングは、1856 &amp;gt; 1760とまとも低下。やむなし。。&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-6791093376766405100?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6791093376766405100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6791093376766405100'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/09/srm366-typo2.html' title='SRM366 - typo2連発'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-7219799914927632057</id><published>2007-07-31T00:07:00.001+09:00</published><updated>2007-07-31T20:27:42.978+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - generatorで素数生成</title><content type='html'>&lt;p&gt;Pythonのgeneratorは無限ストリームを実現するのに便利。
たとえば、 &lt;a class="reference" href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.2"&gt;SICP 3.5.2&lt;/a&gt; 節にでてくる素数の無限ストリーム&lt;/p&gt;
&lt;p&gt;Scheme:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(define (integers-starting-from n)
  (cons-stream n (integers-starting-from (+ n 1))))

(define (sieve stream)
  (cons-stream
   (stream-car stream)
   (sieve (stream-filter
           (lambda (x)
             (not (divisible? x (stream-car stream))))
           (stream-cdr stream)))))

(define primes (sieve (integers-starting-from 2)))
&lt;/pre&gt;
&lt;p&gt;をPythonで実現すると、こうなります。&lt;/p&gt;
&lt;p&gt;Python:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;gt;&amp;gt;&amp;gt; from itertools import ifilter, count
&amp;gt;&amp;gt;&amp;gt; def sieve(g):
...      prime = g.next()
...      yield prime
...      for i in sieve(ifilter(lambda x: x%prime, g)):
...          yield i
...
&amp;gt;&amp;gt;&amp;gt; primes = sieve(count(2))
&amp;gt;&amp;gt;&amp;gt; primes.next()
2
&amp;gt;&amp;gt;&amp;gt; primes.next()
3
&amp;gt;&amp;gt;&amp;gt; primes.next()
5
&amp;gt;&amp;gt;&amp;gt; primes.next()
7
&amp;gt;&amp;gt;&amp;gt; primes.next()
11
&lt;/pre&gt;
&lt;p&gt;しかし、Schemeと異なり、Pythonの場合は、&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;gt;&amp;gt;&amp;gt; for i, prime in enumerate(sieve(count(2))):
...     print &amp;quot;%d th prime is %d&amp;quot; % (i, prime)
...
0 th prime is 2
1 th prime is 3
2 th prime is 5
3 th prime is 7
4 th prime is 11
5 th prime is 13
..
986 th prime is 7793
987 th prime is 7817
988 th prime is 7823
989 th prime is 7829
&amp;lt;type 'exceptions.RuntimeError'&amp;gt;: maximum recursion depth exceeded
&lt;/pre&gt;
&lt;p&gt;と、再帰レベルのリミット(デフォルトでは1000レベル)に引っかかります。&lt;/p&gt;
&lt;p&gt;Schemeではtail-recursionの処理が行われますが、Pythonでは行われないからですね。
パフォーマンスは悪くてもよいとして、上手に再帰を避けつつ、
エレガントに無限ストリームを書くにはどうしたらいいのやら?&lt;/p&gt;
&lt;p&gt;[2007-07-31] 追記&lt;/p&gt;
&lt;p&gt;発見しました。これでいけます。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;gt;&amp;gt;&amp;gt; from itertools import ifilter, count
&amp;gt;&amp;gt;&amp;gt; def sieve():
...     g = count(2)
...     while True:
...         prime = g.next()
...         yield prime
...         g = ifilter(lambda x, prime=prime: x%prime, g)
...
&amp;gt;&amp;gt;&amp;gt; primes = sieve()
&amp;gt;&amp;gt;&amp;gt; for i, prime in enumerate(primes):
...     if i%1000 == 0:
...         print &amp;quot;%d th prime is %d&amp;quot; % (i, prime)
...
0 th prime is 2
1000 th prime is 7927
2000 th prime is 17393
3000 th prime is 27457
4000 th prime is 37831
5000 th prime is 48619
6000 th prime is 59369
7000 th prime is 70663
8000 th prime is 81817
9000 th prime is 93187
10000 th prime is 104743
11000 th prime is 116461
12000 th prime is 128201
13000 th prime is 139907
14000 th prime is 151717
..
&lt;/pre&gt;
&lt;p&gt;また、標準のitertools.ifilterではなく、自前のもの、例えば、&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;gt;&amp;gt;&amp;gt; def sieve():
...
...     def myfilter(pred, g):
...         for i in g:
...             if pred(i):
...                 yield i
...
...     g = count(2)
...     while True:
...         prime = g.next()
...         yield prime
...         g = myfilter(lambda x, prime=prime: x%prime, g)
&lt;/pre&gt;
&lt;p&gt;とした場合は、スタックフレームを消費してしまい、成功しません。
標準のitertools.ifilterを使用すると、Stacklessになるようです。
面白い。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-7219799914927632057?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/7219799914927632057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/7219799914927632057'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/07/python-generator.html' title='Python - generatorで素数生成'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-1825549000390460521</id><published>2007-07-25T00:57:00.001+09:00</published><updated>2007-07-25T01:16:15.672+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>New Launguage - 新言語追加の予定?</title><content type='html'>&lt;p&gt;現在、TopCoderのアルゴリズム・マッチで使用できる言語は、
C++, C#, Java, VBの4つです。ちなみに、この前のSRM356で使用された数は以下のとおり。&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;C++ - 723&lt;/li&gt;
&lt;li&gt;C# - 71&lt;/li&gt;
&lt;li&gt;Java - 296&lt;/li&gt;
&lt;li&gt;VB - 4&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;C++が一番人気。VBが圧倒的不人気です。
TopCoderのForumによりますと、&lt;/p&gt;
&lt;p&gt;&lt;a class="reference" href="http://forums.topcoder.com/?module=Thread&amp;amp;threadID=581215#832198"&gt;Haskell support?&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The next language supported has been chosen and will begin work soon;
unfortunately it's not Haskell.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;新しい言語が数ヶ月後に追加されるようですよ。
残念なことに、Haskellではないことだけは確定していますが。&lt;/p&gt;
&lt;p&gt;Python, Ruby, Erlang, OCaml, Pascalあたりが予想されていますが。
はたして何が追加されることやら。&lt;/p&gt;
&lt;p&gt;とりあえず個人的に予想しておくとするなら、OCamlに一票。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-1825549000390460521?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1825549000390460521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1825549000390460521'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/07/new-launguage.html' title='New Launguage - 新言語追加の予定?'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-3263725085503171478</id><published>2007-07-19T23:26:00.001+09:00</published><updated>2007-07-20T19:42:04.814+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>lxmlでHTMLスクレーピング</title><content type='html'>&lt;p&gt;たまにはPythonでTopCoderの問題を解いてみようと思ってはみたものの，
書いたコードが正しいがどうかどうやってチェックすればいいんだろう？
サポートされているJavaやC++なら，TopCoderのプラクティスルームでSubmitして，テストを走らせればいいんですけど．&lt;/p&gt;
&lt;p&gt;問題文に付属しているような数個のサンプルケースだけでは，テストとしてはもちろん不十分．
実際のシステムテストで使用された入力と正解のフルセットさえ入手できれば，ローカルでもテストを走らせることができるはず．
そう思い，そのようなデータがTopCoderで提供されているかというとちょっと探してみる．
&lt;a class="reference" href="http://www.topcoder.com/tc?module=Static&amp;amp;d1=help&amp;amp;d2=dataFeed"&gt;Data Feeds&lt;/a&gt; を発見したけど，該当データは提供されていない．&lt;/p&gt;
&lt;p&gt;システムテストでどのようなテストが走ったかは，たしかWebでもみれたはず．
たとえば，SRM354のHard問題，RookPlacementなら，正解を提出したPetrの &lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=265123&amp;amp;rd=10711&amp;amp;pm=7658&amp;amp;cr=10574855"&gt;Code&lt;/a&gt; を見れば，
システムテストで使用されたテストケースもすべて載っています．&lt;/p&gt;
&lt;p&gt;「このHTMLページから抜き出せばいいじゃん．」
ということでスクレーピングしてみる．&lt;/p&gt;
&lt;p&gt;まずは、HTMLファイルの取得。
もちろん，ブラウザ上でアクセスしてHTMLを保存してもいいですけど、
ここでは、プログラムの中から取得してみる。
認証チェックがあるので、ページを取得する際は，
認証済みCookieが入ったリクエストでないとはじかれてしまいます．
ふだんブラウザで使用しているCookieを渡してしまうのが一番楽．
Pythonなら，こんな感じ．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [1]: import cookielib, urllib2
In [2]: cj = cookielib.MozillaCookieJar()
In [3]: cj.load('cookies.txt')
In [4]: opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
In [5]: html = opener.open(url).read()
&lt;/pre&gt;
&lt;p&gt;あとは，HTMLをパース． &lt;a class="reference" href="http://codespeak.net/lxml/"&gt;lxml&lt;/a&gt; を使用．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [6]: from StringIO import StringIO
In [7]: from lxml import etree
In [8]: tree = etree.parse(StringIO(html), etree.HTMLParser())
&lt;/pre&gt;
&lt;p&gt;lxmlは，HTMLが多少壊れていても，リカバーしてくれるので，
このようなスクレーピング用途にはもってこいです．
Well-FormattedでないHTMLやXMLをパースするのって，
結構，テーマとしては奥が深いような気もするんですけど，どういうアルゴリズムになってるんですかね．&lt;/p&gt;
&lt;p&gt;HTMLを見る限り、欲しいデータはすべて、このような&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;td class='statText' ...&amp;gt;190&amp;lt;/td&amp;gt;
&lt;/pre&gt;
&lt;p&gt;エレメント内であることがわかりますので、
xpathで該当エレメント内テキストをとりあえず全部取得．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [9]: ts = [t.strip() for t in tree.xpath(&amp;quot;//td[&amp;#64;class='statText']/text()&amp;quot;)]
&lt;/pre&gt;
&lt;p&gt;結果を表示してみると，最初の方は余分なごみです．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [10]: ts[30:40]
Out[11]:
['',
 '',
 '',
 'Test\n            Arguments',
 'Expected Results',
 'Success',
 '4,\n5,\n2',
 '190',
 'Passed',
 '2,\n3,\n3']
&lt;/pre&gt;
&lt;p&gt;'Success'文字列以降だけに絞る．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [12]: ts = ts[ts.index('Success')+1:]
In [13]: ts
Out[14]:
['4,\n5,\n2',
 '190',
 'Passed',
 '2,\n3,\n3',
 '6',
 'Passed',
 '6,\n7,\n20',
 '0',
 'Passed',
 '50,\n25,\n50',
 '879507',
 'Passed',
&lt;/pre&gt;
&lt;p&gt;入力，正解はそれぞれ，3つおきに出現するので&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [15]: testcases = zip(ts[::3], ts[1::3])
In [16]: testcases
Out[17]:
[('4,\n5,\n2', '190'),
 ('2,\n3,\n3', '6'),
 ('6,\n7,\n20', '0'),
&lt;/pre&gt;
&lt;p&gt;入力の各パラメータは，',\n'がセパレータになってるので&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [18]: import re
In [19]: testcases = [(re.split(r',\n', input), expected) for (input, expected) in testcases]
In [20]: testcases
Out[21]:
[(['4', '5', '2'], '190'),
 (['2', '3', '3'], '6'),
 (['6', '7', '20'], '0'),
&lt;/pre&gt;
&lt;p&gt;各データは文字列ですので、evalします．
今回のデータには含まれていないですけど、TopCoderの配列のリテラルは'{..}'形式ですので、evalできるように'[..]'に変換してから．
evalが怖いなら，JSONとしてパースしてもいいです．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [22]: def evalf(s):
    ...:     if len(s) &amp;gt;= 2 and s[0] == '{' and s[-1] == '}':
    ...:         s = '[' + s[1:-1] + ']'
    ...:     return eval(s)
    ...:
In [23]: testcases = [(map(evalf, input), evalf(expected)) for (input, expected) in testcases]
In [24]: testcases
Out[25]:
[([4, 5, 2], 190),
 ([2, 3, 3], 6),
 ([6, 7, 20], 0),
&lt;/pre&gt;
&lt;p&gt;これでOK。あとはテストするだけ。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
In [26]: for input, expected in testcases:
    ...:     assert RooksPlacement().countPlacements(*input) == expected
&lt;/pre&gt;
&lt;p&gt;テストケースを抜き出す部分は、まとめると最終的にはこうなります。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
def extract_testcases(url, cookie_file='cookies.txt'):
    cj = cookielib.MozillaCookieJar()
    cj.load(cookie_file)
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
    html = opener.open(url).read()
    tree = etree.parse(StringIO(html), etree.HTMLParser())
    ts = [t.strip() for t in tree.xpath(&amp;quot;//td[&amp;#64;class='statText']/text()&amp;quot;)]
    ts = ts[ts.index('Success')+1:]
    return [(map(evalf, re.split(r',\n', input)), evalf(expected))
            for (input, expected) in zip(ts[::3], ts[1::3])]
&lt;/pre&gt;
&lt;p&gt;昔はこういうことをしたかったら，Perlで正規表現を書いて抜きだしていたけど，
どうしてもコードが長くなりがち．
いまは，大抵どの言語でも便利なXMLライブラリが付属しているので，楽ちん．&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-3263725085503171478?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/3263725085503171478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/3263725085503171478'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/07/lxmlhtml.html' title='lxmlでHTMLスクレーピング'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-378748696129691026</id><published>2007-07-18T21:16:00.001+09:00</published><updated>2007-07-18T21:18:13.292+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM358 - Today is a Bad Day (-50).</title><content type='html'>&lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=10768"&gt;SRM358&lt;/a&gt; に挑戦。&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7716&amp;amp;rd=10768"&gt;BrokenButtons&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=265496&amp;amp;rd=10768&amp;amp;pm=7716&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題。いかにケアレスミスをしないか?を問われる問題。
で、見事にミスをしてしまいました。しかも、2つも。
5分の休憩時間中に、自分の誤りに気がついたんですけど、ときすでに遅し。
なぜか、自分は、250点問題のミスに、休憩時間中に気付くパターンが多いような。
他人へのチャレンジ・ケースを考えているうちに、自分のミスに気付かされるといういつものパターン。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7845&amp;amp;rd=10768"&gt;BalanceScale&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;500点問題。苦手な整数問題。
最大サイズが50なので、探索できっこないと思い込む。なにかクレバーなアイデアがあるはずと思いつつ、
しかし、時間内に思いつく自信がなかったため、早めにパスして、1000点問題へ。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7834&amp;amp;rd=10768"&gt;SharksDinner&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=265496&amp;amp;rd=10768&amp;amp;pm=7834&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;1000点問題．500点問題よりは取り組みやすそうに思えたので、今回は、ずっとこれに取り組んでいました。
まったく同じ鮫をのぞいてしまえば、グラフはDAG(directed acyclic graph)になるので、まったく同じ鮫をどのように扱うか考えていました。
結局提出まで至らず時間切れ。
後で、コードを振り返ってみると、全体としての方針は間違っていなかったんですけど(DAGにしてマッチング問題に帰着)、
前半部分で、「同じ鮫をひとつにまとめてしまっても大丈夫なはずだ」という、致命的な勘違いをしていました。
なぜ、そう思ったのだろう。。。&lt;/p&gt;
&lt;p&gt;ほとんどのひとは、MaxFlowで解いていますね。なるほど。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=10768"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;チャレンジも2つ失敗して、結局スコア-50で終わるという過去最低の結果に。
レーティングも2040-&amp;gt;1856とものの見事な低下っぷり。
この悔しさが、次回へのモチベーションにつながるんですけどね。&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-378748696129691026?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/378748696129691026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/378748696129691026'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/07/srm358-today-is-bad-day-50.html' title='SRM358 - Today is a Bad Day (-50).'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-2424524944487624606</id><published>2007-05-18T23:54:00.001+09:00</published><updated>2007-05-19T11:20:53.916+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM349 FizzBuzz問題が簡単すぎるそんなあなたへ。「赤いマーブル問題」。</title><content type='html'>&lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;er=5&amp;amp;rd=10673"&gt;SRM349&lt;/a&gt; に挑戦。&lt;/p&gt;
&lt;p&gt;今回は、1000点問題が、なかなかいい問題でした。
Division1の人達の多くを見事にひっかけた良問です。
超絶アルゴリズムが必要なわけではなく、最初にちょっとしたアイデアに気付くかどうかで、
十分に解ける問題と化すという、素晴らしい問題だなと。&lt;/p&gt;
&lt;p&gt;世間ではFizzBuzz問題がはやっていたようですが、
それに飽きたという方は、この1000点問題
「 &lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6067&amp;amp;rd=10673"&gt;赤いマーブル問題&lt;/a&gt; 」に挑戦してみてください。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;中が見えないバッグに、赤いマーブルがred個、青いマーブルがblue個、入っています。
あなた(A君)と相手(B君)は、交互に、バッグから1個、あるいは2個、あるいは3個のマーブルをまとめて取り出します。
取り出したマーブルの色は自分だけでなく相手にも教えてあげます。
このように交互にマーブルを1個から3個ずつ取り出していき、
バッグに入っている最後の(ラスト一個の)赤いマーブルを取り出した人が負けになります。&lt;/p&gt;
&lt;p&gt;それでは、ゲームスタートです。
といいたいところですが、ここで第3者(C君)が現れて、ゲームをはじめる前に、バッグからマーブルを、ランダムにremoved個、取り出してしまいました。
A君もB君も、取り出されたremoved個のマーブルがそれぞれ何色だったかは教えてもらえませんでした。&lt;/p&gt;
&lt;p&gt;この状態からゲームはスタートします。
すなわち、A君とB君は、もともとの赤いマーブル, 青いマーブルの個数と, C君が取り出した個数は知っていますが、
現在のバッグについては、(red + blue - removed)個のマーブルが入っていることがわかっているだけで、どの色がそれぞれ何個入っているかはわかっていません。&lt;/p&gt;
&lt;p&gt;ゲームスタート。最初に取り出しのはあなた(A君)からです。お互いが最適な戦略をとる場合、あなたが勝つ確率はいくつになるでしょうか?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という問題です。&lt;/p&gt;
&lt;p&gt;red, blue, removedは、以下の条件を満たすものとします。&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;1&amp;lt;= red &amp;lt;= 100&lt;/li&gt;
&lt;li&gt;1&amp;lt;= blue &amp;lt;= 100&lt;/li&gt;
&lt;li&gt;removed &amp;lt; red&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、ゲーム開始時は、少なくとも1個、赤いマーブルがバッグに残っています。&lt;/p&gt;
&lt;p&gt;では、どうぞ!&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public double winningChance(int red, int blue, int removed) {
    ...
}
&lt;/pre&gt;
&lt;p&gt;ちなみに&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;red=1, blue=1, removed=0 の場合は、答えは、0.5&lt;/li&gt;
&lt;li&gt;red=1, blue=2, removed=0 の場合は、答えは、0.33333333333333...&lt;/li&gt;
&lt;li&gt;red=2, blue=1, removed=1 の場合は、答えは、0.5&lt;/li&gt;
&lt;li&gt;red=100, blue=1, removed=99 の場合は、答えは、0.9900990099009901...&lt;/li&gt;
&lt;li&gt;red=100, blue=100, removed=50 の場合は、答えは、0.5379240275007613...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;になります。正しく解けたかどうかの検証用にどうぞ。&lt;/p&gt;
&lt;p&gt;ちなみに、トップのひとは、この問題を23分で解いています。。。&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-2424524944487624606?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/2424524944487624606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/2424524944487624606'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/05/srm349-fizzbuzz.html' title='SRM349 FizzBuzz問題が簡単すぎるそんなあなたへ。「赤いマーブル問題」。'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-1391481673953214609</id><published>2007-03-27T00:15:00.000+09:00</published><updated>2007-03-27T12:55:28.154+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>Suffix Array</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;TopCoder SRM187、 &lt;a href='http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=2224&amp;amp;rd=4755' class='reference'&gt;DNAMultiMatcher&lt;/a&gt; は、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Stringが3つ(それぞれの長さは最大2500)与えられたとき、
3つ全てに含まれる最長のSubstringの長さを求めなさい。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という問題です。これに対して、&lt;/p&gt;
&lt;ul class='simple'&gt;
&lt;li&gt;長さをBinary-Searchで絞りながら、&lt;/li&gt;
&lt;li&gt;Stringが含まれるかどうかの判定をJava標準のjava.lang.String#containsを使用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という方針で解く場合は、こうなります。&lt;/p&gt;
&lt;pre class='literal-block'&gt;
public class DNAMultiMatcher {

  public int longestMatch(String[] sequence1, String[] sequence2, String[] sequence3) {
      String s1 = join(sequence1);
      String s2 = join(sequence2);
      String s3 = join(sequence3);

      int low = 0;
      int high = s1.length();

      while (low &amp;lt; high) {
          int mid = low + (high-low+1)/2;
          boolean found = false;
          for (int i = 0; i + mid &amp;lt;= s1.length(); i++) {
              String p = s1.substring(i, i+mid);
              if (s2.contains(p) &amp;amp;&amp;amp; s3.contains(p)) {
                  found = true;
                  break;
              }
          }
          if (found) {
              low = mid;
          } else {
              high = mid-1;
          }
      }
      return low;
  }

  String join(String[] sa) {
      StringBuilder sb = new StringBuilder();
      for (String s : sa) sb.append(s);
      return sb.toString();
  }
}
&lt;/pre&gt;
&lt;p&gt;この場合は、ワーストケースで軽く2分以上かかってしまい、タイムアウトです。
String Aの長さをn、String Bの長さをmとした場合、JavaのA.contains(B)は、
普通にO(m*n)っぽいですね。&lt;/p&gt;
&lt;p&gt;AがBを含んでいるか?を高速に判定するときに使用できるのが、 &lt;a href='http://en.wikipedia.org/wiki/Suffix_array' class='reference'&gt;Suffix Array&lt;/a&gt; です。&lt;/p&gt;
&lt;p&gt;ナイーブに実装してみると、&lt;/p&gt;
&lt;pre class='literal-block'&gt;
class SuffixArray {
    int len;
    String[] suffixes;

    SuffixArray(String s) {
        len = s.length();
        suffixes = new String[len];
        for (int i = 0; i &amp;lt; len; i++) {
            suffixes[i] = s.substring(i);
        }
        Arrays.sort(suffixes);
    }

    int find(String p) {
        if (len == 0) {
            return p.length() == 0 ? 0 : -1;
        }
        int low = 0;
        int high = suffixes.length-1;
        while (low &amp;lt; high) {
            int middle = low + (high-low)/2;
            if (suffixes[middle].compareTo(p) &amp;gt;= 0) {
                high = middle;
            } else {
                low = middle+1;
            }
        }
        if (suffixes[high].startsWith(p)) {
            return len - suffixes[high].length();
        }
        return -1;
    }
}
&lt;/pre&gt;
&lt;p&gt;Javaのjava.lang.String#substringメソッドは、
もとのStringと内部の配列char[]を共有したStringを返すので、
この実装でも無駄にメモリを消費しないはずです。&lt;/p&gt;
&lt;p&gt;オーダーは、&lt;/p&gt;
&lt;ul class='simple'&gt;
&lt;li&gt;Aに対するSuffix Arrayの構築: O(n^2 log(n))&lt;/li&gt;
&lt;li&gt;AがBを含んでいるかの判定: O(m log(n))&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;になるでしょうか?
改良の余地はまだまだ残っていますが、今回の目的にはこれで十分です。
(Suffix ArrayをO(n)で作成するアルゴリズムもあるようです。。。)&lt;/p&gt;
&lt;p&gt;先ほどの例を、Suffix Arrayを使用して書き直すとこうなります。&lt;/p&gt;
&lt;pre class='literal-block'&gt;
public class DNAMultiMatcher {

  public int longestMatch(String[] sequence1, String[] sequence2, String[] sequence3) {
      String s1 = join(sequence1);
      String s2 = join(sequence2);
      String s3 = join(sequence3);

      SuffixArray sa2 = new SuffixArray(s2);
      SuffixArray sa3 = new SuffixArray(s3);

      int low = 0;
      int high = s1.length();

      while (low &amp;lt; high) {
          int mid = low + (high-low+1)/2;
          boolean found = false;
          for (int i = 0; i + mid &amp;lt;= s1.length(); i++) {
              String p = s1.substring(i, i+mid);
              if (sa2.find(p) &amp;gt;= 0 &amp;amp;&amp;amp; sa3.find(p) &amp;gt;= 0) {
                  found = true;
                  break;
              }
          }
          if (found) {
              low = mid;
          } else {
              high = mid-1;
          }
      }
      return low;
  }
&lt;/pre&gt;
&lt;p&gt;これで、ワーストケースでも1秒以内に処理できるようになり、システムテストに通ります。
Suffix Arrayの応用例はほかにもいろいろあり、全文検索などでもよく使われるようです。&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-1391481673953214609?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1391481673953214609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1391481673953214609'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/03/suffix-array_27.html' title='Suffix Array'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-5491597710803920210</id><published>2007-03-26T23:45:00.000+09:00</published><updated>2007-03-27T01:39:28.509+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><title type='text'>google-code-prettifyを導入してみる</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;&lt;a href='http://code.google.com/p/google-code-prettify/' class='reference'&gt;google-code-prettify&lt;/a&gt; を導入してみました。
JavaScript + CSSでコード部分の色つけをしてくれるものです。&lt;/p&gt;
&lt;p&gt;デフォルトでは、class属性が"prettyprint"となっている、
&amp;lt;pre&amp;gt;タグや&amp;lt;code&amp;gt;タグがシンタックス・ハイライトの対象になるようです。
このブログはreStructuredTextで書いているので、
&amp;lt;pre&amp;gt;タグのclass属性は、clsss="literal-block"となっています。
&amp;lt;pre&amp;gt;タグの方を直すのはいまさら面倒なので、prettify.jsの方を少し修正して導入しました。
PythonとJavaは両方ともサポート言語ですので、どちらもなかなか派手に色がつきます。&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-5491597710803920210?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/5491597710803920210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/5491597710803920210'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/03/google-code-prettify_26.html' title='google-code-prettifyを導入してみる'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-1943394391388127967</id><published>2007-03-02T01:00:00.000+09:00</published><updated>2007-03-27T01:11:28.608+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>Subsetの生成</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;いままで、あるビットマスクsupersetのサブセットをすべて生成するには、&lt;/p&gt;
&lt;pre class='literal-block'&gt;
for (int subset = 1; subset &amp;lt; superset; subset++) {
 if ((subset|superset) == superset) {
   // do with subset
 }
}
&lt;/pre&gt;
&lt;p&gt;としていたんですけど、これだと、
superset = 10011(2)などの場合でも、約10011(2)回のループが必要です。
生成されるサブセットは、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;{10010, 10001, 00011, 10000, 00010, 00001,}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と6つしかないのに。すごい無駄です。&lt;/p&gt;
&lt;p&gt;もっとうまい方法がありました。&lt;/p&gt;
&lt;pre class='literal-block'&gt;
for (int subset = superset; subset &amp;gt; 0; subset = (subset-1) &amp;amp; superset) {
  // do with subset
}
&lt;/pre&gt;
&lt;p&gt;これなら、サブセットのみをうまく生成できます。
この場合のサブセットはsupersetを含み、空セットは含みません。&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-1943394391388127967?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1943394391388127967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1943394391388127967'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2007/03/subset.html' title='Subsetの生成'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-1177943029787130999</id><published>2006-12-31T01:17:00.000+09:00</published><updated>2006-12-31T01:49:18.672+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>2006年のまとめ - SRM332</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;&lt;a href='http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=10012' class='reference'&gt;SRM332&lt;/a&gt; に挑戦。2006年、最後のSRMになります。&lt;/p&gt;
&lt;div class='section'&gt;
&lt;h2&gt;&lt;a href='http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7309&amp;amp;rd=10012' class='reference'&gt;CreatePairs&lt;/a&gt; (&lt;a href='http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=263121&amp;amp;rd=10012&amp;amp;pm=7309&amp;amp;cr=15632820' class='reference'&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題。Greedyですね。落ち着けばとけます。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;&lt;a href='http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6402&amp;amp;rd=10012' class='reference'&gt;RestoringPolygon&lt;/a&gt; (&lt;a href='http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=263121&amp;amp;rd=10012&amp;amp;pm=6402&amp;amp;cr=15632820' class='reference'&gt;Code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;550点問題。2次元平面上で水平の線分(セグメント)がいくつか与えられます。
このセグメントに垂直のセグメントを好きなだけ足して、
最大のポリゴンを作成して、その辺の数を返しなさい。という問題です。&lt;/p&gt;
&lt;p&gt;単純に考えてそのまま強引に解いてしまいました。
ワーストケースでのタイムアウトが気になりましたが大丈夫だったようです。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;&lt;a href='http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6175&amp;amp;rd=10012' class='reference'&gt;LadderPermutation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;950点問題．Openしませんでした。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a href='http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=10012&amp;amp;rm=263121' class='reference'&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;550点問題のRestoringPolygonをシステムテストで落とされた人が続出
( &lt;a href='http://www.topcoder.com/tc?module=ProblemDetail&amp;amp;rd=10012&amp;amp;pm=6402' class='reference'&gt;309人中、提出が144、正解が16と正解率が11%ほど&lt;/a&gt; )したため、
全体的に点数が低めでした。
950点問題のほうが、550点問題より正解者が多い。。。&lt;/p&gt;
&lt;img src='http://farm1.static.flickr.com/149/338406108_a8c377433c_o.png' alt='Room Statistics'&gt;&lt;/img&gt;
&lt;p&gt;なぜか同じルーム内にはRed Coderがいなかったため、ルーム内ではトップのポイント。
レーティングは1532-&amp;gt;1678と上昇しました。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;2006年のまとめ&lt;/h2&gt;
&lt;p&gt;2006年も終了。この時点でのStatsを記録として残しておきます。&lt;/p&gt;
&lt;img src='http://farm1.static.flickr.com/156/338419927_1cb351d94a_o.png' alt='Rationg History'&gt;&lt;/img&gt;
&lt;p&gt;今年のはじめはレーティングが1630で、今は1678ですのであんまり変わってません。&lt;/p&gt;
&lt;img src='http://farm1.static.flickr.com/127/338428423_92a7a00025_o.png' alt='Rating Distribution'&gt;&lt;/img&gt;
&lt;p&gt;まだまだRed Coderへは遠い道のりです。。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;Pythonはどうなった?&lt;/h2&gt;
&lt;p&gt;TopCoderに参加するときはこれまでのところJavaをずっと使用していますが、
TopCoder以外の個人的な場面ではJavaを使用することはすっかりなくなり、
大抵の場合Pythonを使用しています。
でもあいかわらず、TopCoderのアルゴリズム・マッチで使用できる言語は、
Java、C#、C++、VBの4つだけでPythonは採用されそうもありません。
他言語とのスピード差がその理由だそうです。
アルゴリズム・マッチで走らせるプログラムは外とのI/Oがまったくなく
ほぼCPUだけに全体の処理時間が依存してしまうので、
どうしてもスピード差が顕著になってしまうわけですね。
そうはいっても、今年のGoogle Code JamではPythonは採用されたわけだが。。。&lt;/p&gt;
&lt;p&gt;と思っていたら、TopCoderのマラソン・マッチでは
Pythonがいつのまにか使用言語として採用されています。
アルゴリズム・マッチと異なり、マラソン・マッチはコンテストの性質上、
処理時間をあまり気にする必要がないのでPythonを加えたそうです。
じっくり未解決の難問に取り組むマラソン・マッチもやってみたいところだが、
さすがにアルゴリズム部門と比べて時間がそれなりにとられそうなので
しばらくは見送り。&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-1177943029787130999?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1177943029787130999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1177943029787130999'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/12/2006-srm332.html' title='2006年のまとめ - SRM332'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-6317802081866962873</id><published>2006-12-26T01:59:00.001+09:00</published><updated>2006-12-26T03:08:14.164+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM331 - お釣りを受け取らないで、ちょうど支払うには?</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;&lt;a href='http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=10011' class='reference'&gt;SRM331&lt;/a&gt; に挑戦。今回は、500点問題がシンプルでいい問題でした。&lt;/p&gt;
&lt;div class='section'&gt;
&lt;h2&gt;&lt;a href='http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7280&amp;amp;rd=10011' class='reference'&gt;CarolsSinging&lt;/a&gt; (&lt;a href='http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=263049&amp;amp;rd=10011&amp;amp;pm=7280&amp;amp;cr=15632820' class='reference'&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題。総当たりでいけます。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;&lt;a href='http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6479&amp;amp;rd=10011' class='reference'&gt;Shopping&lt;/a&gt; (&lt;a href='http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=263049&amp;amp;rd=10011&amp;amp;pm=6479&amp;amp;cr=15632820' class='reference'&gt;Code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題。&lt;/p&gt;
&lt;p&gt;買いものにでかけるところです。
目的の商品の値段は、1円以上X円以下であることが事前にわかっていますが、
実際の値段はお店に着いてみないとわかりません。
そのお店はどういうわけかお釣りを出してくれないお店です。
そこで損をしないためには、商品がどんな値段であっても、
手持ちの何種類かの小銭(コイン)を組み合わせて
値段ちょうどの金額を支払うことができるように準備しておきたいところです。
コインは必要以上にたくさん持ち歩きたくはありません。
あらかじめ用意しておかなければいけない、最低限必要なコインは何枚でしょうか?
という問題です。&lt;/p&gt;
&lt;p&gt;問題の入力と条件は、&lt;/p&gt;
&lt;ul class='simple'&gt;
&lt;li&gt;商品の値段: int X (1&amp;lt;=X&amp;lt;=1000)&lt;/li&gt;
&lt;li&gt;コインの種類: int[] values&lt;ul&gt;
&lt;li&gt;10種類まで (values.length &amp;lt;= 10) です。&lt;/li&gt;
&lt;li&gt;たとえば日本の硬貨の場合は、int[] values = {1, 5, 10, 50, 100, 500}。&lt;/li&gt;
&lt;li&gt;各コインは家には無限個あるとします。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;求められる出力は&lt;/p&gt;
&lt;ul class='simple'&gt;
&lt;li&gt;必要なコインの最小枚数。
もちろん、コインの種類によっては不可能な場合もありますので、
その場合は -1。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;たとえば、X = 100, values = {1, 5, 10, 50, 100, 500} の場合は、
答えは、11枚になります。
11枚の例としては、[1,1,1,1,5,10,10,10,10,50,100]などです。
これなら、1円から100円までどんな値段であってもきっちり支払うことができます。&lt;/p&gt;
&lt;p&gt;さあ、挑戦してみてください。&lt;/p&gt;
&lt;pre class='literal-block'&gt;
int minNumber(int X, int[] values) {
   ?????
}
&lt;/pre&gt;
&lt;ul class='simple'&gt;
&lt;li&gt;10分以内にできたら、なかなかのものです。&lt;/li&gt;
&lt;li&gt;30分以内にできたら、わたしとおんなじ位です。まだまだTopCoderには及びません...。&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;&lt;a href='http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=7265&amp;amp;rd=10011' class='reference'&gt;HiddenSquares&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．時間さえあればなんとかなるという問題なんですけど、
間に合いませんでした。。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a href='http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=10011&amp;amp;rm=263049' class='reference'&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img src='http://farm1.static.flickr.com/147/332878982_6b681cf4cf_o.png' alt='Room Statistics'&gt;&lt;/img&gt;
&lt;p&gt;ここのところレーティングが下がる一方だったんですけど、
今回はようやく1445-&amp;gt;1532と上昇。
Yellow Nameに返り咲きました。&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-6317802081866962873?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6317802081866962873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/6317802081866962873'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/12/srm331.html' title='SRM331 - お釣りを受け取らないで、ちょうど支払うには?'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-3046389304958471988</id><published>2006-10-31T23:00:00.000+09:00</published><updated>2006-11-01T00:22:10.824+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google code jam'/><title type='text'>Google Code Jam 2006 - Championship Round</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;Google Code Jam 2006、Championship Roundが開催されました。
オンラインラウンドを勝ち抜いた100名が、Googleニューヨーク・オフィスに招待されて対決です。
結果は、&lt;/p&gt;
&lt;img src='http://static.flickr.com/121/284664008_4797661794_o.png' alt='Google Code Jam 2006 Championship Round Result'&gt;&lt;/img&gt;
&lt;p&gt;見事Petrが栄冠を勝ち取りました。Petr強い。
Googleから &lt;a href='http://www.google.com/press/pressrel/codejamwinners_2006.html' class='reference'&gt;プレス・リリース&lt;/a&gt; もでてます。&lt;/p&gt;
&lt;p&gt;Google Code Jamの問題は、これまでのところ公開されていないようです。
いま、Code Jamのアリーナにアクセスすると、出題された問題セットを見ることができますので、見たい人はお早めにどうぞ。&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-3046389304958471988?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/3046389304958471988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/3046389304958471988'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/11/google-code-jam-2006-championship-round.html' title='Google Code Jam 2006 - Championship Round'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-5236776380209684363</id><published>2006-10-31T04:04:00.001+09:00</published><updated>2006-11-04T11:07:51.815+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Blogger Betaに移行</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;Blogger Betaに移行してみました。大きな変更点としては&lt;/p&gt;
&lt;ul class='simple'&gt;
&lt;li&gt;Labelが使えるようになった&lt;/li&gt;
&lt;li&gt;テンプレート・システムがまったく新しくなっている&lt;/li&gt;
&lt;li&gt;ページを動的に作成するようになったので、テンプレートを変更するとすぐにページに反映される&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;といったところでしょうか？&lt;/p&gt;
&lt;div class='section'&gt;
&lt;h2&gt;テンプレート・システム&lt;/h2&gt;
&lt;p&gt;新しいテンプレート・システムのうりのひとつは、ブラウザ上でGUIでデザインできることです。
必ずGUIを使う必要はなく、全部自分で手作業で設定することももちろん可能でした。
いい機会ですので、新規にテンプレート・CSSを作成してみました。
テンプレートのタグも新規タグが用意されています。
これまでより細部で機能アップしてますね。
ほとんど全ての箇所をいじることができる自由度は相変わらず健在ですので、
特にデザイン上支障はありません。
GUIデザイン用に使用されるテンプレート内の変数部分は、わずらわしいので全部消去しました。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;スタイルシートの動的切り替え&lt;/h2&gt;
&lt;p&gt;「Printer Friendly View」 は &lt;a href='http://alistapart.com/stories/alternate/' class='reference'&gt;Alternative Style: Working With Alternate Style Sheets&lt;/a&gt; を参考にしてみました。
スタイルシートを動的に切り替えることができます。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;Google Data APIs&lt;/h2&gt;
&lt;p&gt;ブラウザから記事を投稿する人には関係のない話ですが、
私の場合は、記事は &lt;a href='http://docutils.sourceforge.net/rst.html' class='reference'&gt;reStructuredText&lt;/a&gt;  形式でローカルで書いてから、
自作のPythonスクリプトで記事を投稿できるようにしています。
Bloggerでは、そのためにATOM APIが用意されています。
こちらもBetaでは変更が入り、 &lt;a href='http://code.google.com/apis/gdata/' class='reference'&gt;Google Data APIs&lt;/a&gt; を用いるようになりました。&lt;/p&gt;
&lt;p&gt;主な変更点としては、&lt;/p&gt;
&lt;ul class='simple'&gt;
&lt;li&gt;ATOM APIのバージョンが0.3から1.0に変更&lt;/li&gt;
&lt;li&gt;認証システムも、Basic認証から、 &lt;a href='http://code.google.com/apis/accounts/Authentication.html' class='reference'&gt;Google Account Authentication&lt;/a&gt; に変更&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;といったところです。
&lt;a href='http://code.google.com/apis/gdata/blogger.html' class='reference'&gt;Blogger Data API&lt;/a&gt; として使用方法が解説してありますので、ここを見れば簡単です。&lt;/p&gt;
&lt;p&gt;JavaやC#用のクライアント・ライブラリも用意されていましたが、
reStructutedTextの変換を考えるとやはりPythonのほうがよいと思い、
Pythonでクライアントを書きました。
ATOMを使用するにあたり、いくつかすんなりとはいかなかった点としては、&lt;/p&gt;
&lt;ol class='arabic simple'&gt;
&lt;li&gt;指定されたPost先にPost要求を出すと、Betaのサーバはリダイレクトを返してきます。&lt;/li&gt;
&lt;li&gt;投稿に成功した場合、ステータスコード201を返してきます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この2点です。
Pythonの標準のAPI(urllib/urllib2)では、Post要求に対してリダイレクトが返って来ると、
リダイレクト先へPostを再送するのではなくGet要求を出してしまいます。
また、ステータスコード201もエラー扱いするようになっていました。
そのため、自分で &lt;tt class='docutils literal'&gt;&lt;span class='pre'&gt;urllib2.HTTPRedirectHandler&lt;/span&gt;&lt;/tt&gt; をもとにした、ちょっとしたハックが必要になります。&lt;/p&gt;
&lt;p&gt;その他に気づいた問題点は、新規記事をATOM 1.0で送る時、&amp;lt;published&amp;gt;での日付指定が無視されてしまうことです。
これは、現在サーバ側の問題らしく、 &lt;a href='http://groups.google.com/group/bloggerDev/' class='reference'&gt;Blogger Dev Group&lt;/a&gt; で議論されていますのでいずれ解決しそうです。&lt;/p&gt;
&lt;p&gt;これでほぼ移行作業が完了しましたが、全体としてはBetaの方がはるかに使いやすくなりましたね。
なによりラベルが使えるようになったのがいちばんうれしいですね。&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-5236776380209684363?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/5236776380209684363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/5236776380209684363'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/10/blogger-beta.html' title='Blogger Betaに移行'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-115829354260826244</id><published>2006-09-15T18:30:00.000+09:00</published><updated>2006-10-31T22:30:41.054+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google code jam'/><title type='text'>Google Code Jam 2006 - Round1に挑戦 - GenericsとAutoBoxing</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;Google Code Jam 2006 Round1に挑戦。
予選を通過した1000名のうち500名が通過できます。&lt;/p&gt;
&lt;div class='section'&gt;
&lt;h2&gt;NearFrac&lt;/h2&gt;
&lt;p&gt;250点問題。
問題の条件をまちがって解釈してしまいました。
解が複数あった場合、たとえば「-1/3, -2/3」の場合は、「小さいほう」である「-2/3」を優先しなければいけないんですが、
「小さいほう」の説明を逆に解釈してしまい、「-1/3」を優先するようなコードを書いてしまいました。
よく問題を読めばちゃんと説明してあるんですけどね。反省。&lt;/p&gt;
&lt;/div&gt;
&lt;div class='section'&gt;
&lt;h2&gt;BadBinary&lt;/h2&gt;
&lt;p&gt;500点問題。
問題自体は難しくなくコーディングはさくさく10分ほどで完了。
しかし、Javaの罠にはまってしまいました。。。
たとえば、&lt;/p&gt;
&lt;pre class='literal-block'&gt;
Map&amp;lt;Long, Long&amp;gt; memo = new HashMap&amp;lt;Long, Long&amp;gt;();
long i = 1;
memo.put(i, 2);
&lt;/pre&gt;
&lt;p&gt;として、このMapから値を取得しようと、&lt;/p&gt;
&lt;pre class='literal-block'&gt;
int j = 1;
memo.get(j);
&lt;/pre&gt;
&lt;p&gt;とします。するとmemo.get(j)の結果は、2ではなくnullになってしまいます。
memoは&lt;/p&gt;
&lt;pre class='literal-block'&gt;
Map&amp;lt;Long, Long&amp;gt; memo
&lt;/pre&gt;
&lt;p&gt;と宣言しているので、memo.get(j)の部分は、AutoBoxingが働いて&lt;/p&gt;
&lt;pre class='literal-block'&gt;
memo.get(new Long(j))
&lt;/pre&gt;
&lt;p&gt;と解釈されると思っていたのですが、実際は&lt;/p&gt;
&lt;pre class='literal-block'&gt;
memo.get(new Integer(j))
&lt;/pre&gt;
&lt;p&gt;とIntegerになるようですね。int-&amp;gt;longの変換は行われません。
当然、memo.put(new Long(1), ..)したものは、memo.get(new Integer(1))では取得できません。&lt;/p&gt;
&lt;p&gt;「Genericsのもつコンパイル時の型チェックは機能しないのか？」
と思ったら、そもそもMapのメソッドgetは&lt;/p&gt;
&lt;pre class='literal-block'&gt;
public interface Map&amp;lt;K,V&amp;gt; {
  V get(Object key);
&lt;/pre&gt;
&lt;p&gt;と定義されているんですね。てっきり&lt;/p&gt;
&lt;pre class='literal-block'&gt;
public interface Map&amp;lt;K,V&amp;gt; {
  V get(K key);
&lt;/pre&gt;
&lt;p&gt;だと思いこんでいました。パラメータの型チェックは行われないのか。。がく。&lt;/p&gt;
&lt;p&gt;本番中はまさかこの部分に問題があるとは気づくことができず右往左往。
なぜかこういうときだけ無駄な想像力が異様に働き、関係ないところばかり追いかけてしまいました。
むなしく時間（50分も。。）を費やしたあげく、結局最後まで気づくことができないまま時間切れ。
memo.get(j)ではなくmemo.get((long)j)とするだけでよかったんですけど。気づくべきでした。
Google Code Jamくん、楽しませてもらったよ。また来年までさようなら。&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-115829354260826244?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115829354260826244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115829354260826244'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/09/google-code-jam-2006-round1.html' title='Google Code Jam 2006 - Round1に挑戦 - GenericsとAutoBoxing'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-1255909609455667947</id><published>2006-09-09T23:00:00.000+09:00</published><updated>2006-11-04T11:18:54.771+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google code jam'/><title type='text'>Google Code Jam 2006 - Qualification Round通過</title><content type='html'>
    &lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;
    &lt;p&gt;予選通過のメールがきました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From: The Google Code Jam Team&lt;/p&gt;
&lt;p&gt;Subject: Google(TM) Code Jam 2006 Results&lt;/p&gt;
&lt;p&gt;Hello gentoo,&lt;/p&gt;
&lt;p&gt;Congratulations! The results of the Google Code Jam 2006 Qualification Round have been officially tabulated, and we're happy to announce that you have advanced to Round 1. This is a great accomplishment.&lt;/p&gt;
&lt;p&gt;Round 1 of Google Code Jam 2006 takes place online at 10:00 AM EDT (GMT/UTC -4) on Thursday, September 14. Registration is required for this round and will be open from 7:00 AM to 9:55 AM EDT (GMT/UTC -4) on the day of the event. To register for Round 1, log in to the Competition Arena, click on the Active Contests menu item, select Round One, and select Register: www.google.com/codejam2006.&lt;/p&gt;
&lt;p&gt;Of those who participate in Round 1, the top 500 scores will advance to Round 2 on Tuesday, September 19, at 10:00 AM EDT (GMT/UTC -4).&lt;/p&gt;
&lt;p&gt;Congratulations again on successfully making it through the Qualification Round of Google Code Jam 2006.&lt;/p&gt;
&lt;p&gt;- The Google Code Jam Team&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Google Code Jam 2006のサイトにも &lt;a href='http://www.topcoder.com/pl/?&amp;amp;module=Static&amp;amp;d1=google06&amp;amp;d2=advQual' class='reference'&gt;通過者の一覧&lt;/a&gt; が正式に出ていますね。
次は、Round1、1000名から500名です。&lt;/p&gt;
    &lt;/div&gt;
    &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-1255909609455667947?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1255909609455667947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/1255909609455667947'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/09/google-code-jam-2006-qualification_09.html' title='Google Code Jam 2006 - Qualification Round通過'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-115753479102669641</id><published>2006-09-06T18:30:00.000+09:00</published><updated>2006-10-29T01:11:57.379+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google code jam'/><title type='text'>Google Code Jam 2006 - Qualification Roundに挑戦</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;いよいよ始まりましたGoogle Code Jam 2006。予選に挑戦です。
5つあるセットのうち、Set 5にアサインされました。
各セットの上位200名、計1000名が予選を通過できます。&lt;/p&gt;
&lt;p&gt;ちょうど、17:00に開始しました。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(17:00:02) System&amp;gt; gentoo is opening the 250-point problem.
&lt;/pre&gt;
&lt;p&gt;250点問題にちょっとてこずり、15分以上かかり提出。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(17:15:51) System&amp;gt; gentoo is compiling the 250-point problem.
(17:15:58) System&amp;gt; gentoo is testing the 250-point problem.
(17:16:08) System&amp;gt; gentoo has submitted the 250-point problem for 176.79 points
&lt;/pre&gt;
&lt;p&gt;この250点問題のスコアでは、とれもこれだけで予選を通過できそうもありません。
確実に750点問題を解かなければいけない状況になってしまいました。
750点問題をオープン。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(17:16:14) System&amp;gt; gentoo is opening the 750-point problem.
&lt;/pre&gt;
&lt;p&gt;15分ほどで提出。これで通るだろうと思いほっと一息。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(17:31:24) System&amp;gt; gentoo is compiling the 750-point problem.
(17:31:30) System&amp;gt; gentoo is testing the 750-point problem.
(17:31:35) System&amp;gt; gentoo has submitted the 750-point problem for 542.17 points
&lt;/pre&gt;
&lt;p&gt;ところが見直してみると、バグ発見。。。修正して、再提出。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(17:37:12) System&amp;gt; gentoo is compiling the 750-point problem.
(17:37:17) System&amp;gt; gentoo has submitted the 750-point problem for 385.45 points
&lt;/pre&gt;
&lt;p&gt;542 -&amp;gt; 385 と大幅に再提出ペナルティを食らいます。。。いたい。。&lt;/p&gt;
&lt;p&gt;最終的はポイントは、176.79 + 385.45 = 562.24。Set 5内の順位は、現在のところ109位です。
まだ全員が参加しているわけではないのでなんともいえませんが、
システムテストに2問ともパスすれば予選通過できそうな範囲にはなんとかおさまりました。
ふー。あとは祈るのみです。&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-115753479102669641?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115753479102669641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115753479102669641'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/09/google-code-jam-2006-qualification.html' title='Google Code Jam 2006 - Qualification Roundに挑戦'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-115570083078395374</id><published>2006-08-16T22:00:00.000+09:00</published><updated>2006-10-29T01:11:57.308+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google code jam'/><title type='text'>Google Code Jam 2006 - Practice1</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;Google Code Jam 2006 、練習部屋が用意されていたので早速練習してみました。&lt;/p&gt;
&lt;p&gt;まず、250点問題。
スタート都市(index=0)からゴールの都市(index=1)まで、セールスマンを何人派遣できるでしょうか？という問題です。
都市通しのつながり(adj)は、&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"001111",
"001111",
"110000",
"110000",
"110000",
"110000"
&lt;/pre&gt;
&lt;p&gt;このようにマトリックス形式で与えられます。都市の数は最大12です。
入力の条件としてスタート都市とゴール都市は、直接つながっていないことが保障されています（adj[0][1] == adj[1][0] == 0です）。
スタート都市とゴールの都市を除いた、途中の通過都市はそれぞれ最大1人のセールスマンだけが通過できます。つまりあるセールスマンが通過した都市は、別のセールスマンは通過できません。
この入力の場合は、正解は4人です([0 -&amp;gt; 2 -&amp;gt; 1], [0 -&amp;gt; 3 -&amp;gt; 1], [0 -&amp;gt; 4 -&amp;gt; 1], [0 -&amp;gt; 5 -&amp;gt; 1]の4通り)。&lt;/p&gt;
&lt;p&gt;いつもはJavaですが、せっかくですのでPythonで書いてみました。&lt;/p&gt;
&lt;pre class="literal-block"&gt;
class SalesRouting:

  def howMany(self, adj):

      def doit(u, mask):
          if (u, mask) in memo: return memo[u,mask]
          if adj[u][1] == '1': return doit(0, mask) + 1
          memo[u,mask] = max([0] +
                             [doit(v, mask | 1&amp;lt;&amp;lt;v) for v in range(2, len(adj))
                              if adj[u][v] == '1' and (mask &amp;amp; (1&amp;lt;&amp;lt;v)) == 0])
          return memo[u,mask]

      memo = {}
      return doit(0, 0)
&lt;/pre&gt;
&lt;p&gt;状態空間は、現在いるcity: u(N通り) と、
これまで通過したcity全て: mask(2^N通り)の組み合わせになります。
ワーストケースでもたかだか12 * 2^12 = 50,000ほどですので、Pythonでも十分通ります。&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-115570083078395374?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115570083078395374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115570083078395374'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/08/google-code-jam-2006-practice1.html' title='Google Code Jam 2006 - Practice1'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-115561555203465855</id><published>2006-08-15T22:00:00.000+09:00</published><updated>2006-10-29T01:11:57.233+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google code jam'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Google Code Jam 2006 - 開催決定</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/pl/?&amp;amp;module=Static&amp;amp;d1=google06&amp;amp;d2=overview"&gt;Google Code Jam&lt;/a&gt; 、今年も開催がアナウンスされました。&lt;/p&gt;
&lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/pl/?&amp;amp;module=Static&amp;amp;d1=google06&amp;amp;d2=overview"&gt;&lt;img alt="codejam2006" src="http://static.flickr.com/86/215584279_136594f8c8_o.gif"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;注目すべきは、なんといってもここでしょう。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The competition is available in five programming languages - Java, C++, C#, VB.NET and Python.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;おー、Pythonが追加されています！！
本家、TopCoderのシステムでは、使用できる言語は、Java, C++, C#, VB.NETだけで、Pythonは使用できません。
にもかかわらず、Google Code Jamといういちイベントのために、わざわざシステムを修正してまでPythonを入れてきたことから、GoogleのPythonに対する意気込みが伝わってきますね。
この思いに答えて、Javaではなく、Pythonでいきたいですね。&lt;/p&gt;
&lt;p&gt;しかし、JavaにくらべてPythonは10倍くらい遅いんですけど、
今回はそれほど時間がシビアな問題は出題されないってことでしょうか？
TopCoderの通常のSRMでは、ワーストケースのオーダーが10,000,000ほどになり、、
実行時間がC++で500ms、Javaで1000msくらいかかってしまう問題が時々出題されます。
と思っていたら、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NOTE: All submissions have a maximum of 2 seconds of runtime per test case.  This limit is used in harder problems to force submissions to be of a certain complexity.  Because of the inherent speed differences between Python and the other offered languages is large, some problems may require extra optimization or not be solvable using the Python language.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と書いてありました。
主催者側もPythonで解けない問題を出してしまうことへあらかじめ保険をかけてますね&lt;/p&gt;
&lt;p&gt;しかし、Pythonが追加されたことでますます盛り上がりそうですね。
普段のTopCoderでもPythonを追加してくれという要望は非常に多かったです。
いったいどれくらいの人がPythonにスイッチするでしょうかね？楽しみです。&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-115561555203465855?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115561555203465855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115561555203465855'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/08/google-code-jam-2006.html' title='Google Code Jam 2006 - 開催決定'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-115330818639411887</id><published>2006-07-19T20:18:00.000+09:00</published><updated>2006-10-29T01:11:57.161+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google code jam'/><title type='text'>Stay tuned... Global Google Code Jam 2006 - 秋に開催?</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;毎年、恒例らしいGoogle Code Jamですが、今年はこれまで&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="http://www.topcoder.com/pl/?module=Static&amp;amp;d1=gicj06&amp;amp;d2=overview"&gt;Google Code Jam India&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="http://www.google.com/codejameurope/"&gt;Google Code Jam Europe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;と地域限定で開催されていました。
世界中の誰でも参加できるグローバルなやつは果たして今年は開催されるのか？と思っていたら、
既に終了したGoogle Code Jam Europeのサイトに以下の記述がありました。&lt;/p&gt;
&lt;img alt="Stay tuned for Global Code Jam 2006, coming this Fall." src="http://static.flickr.com/70/193302335_39f32eaaec_o.png"/&gt;
&lt;p&gt;秋に開催されるみたいですよ。&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-115330818639411887?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115330818639411887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115330818639411887'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/07/stay-tuned-global-google-code-jam-2006.html' title='Stay tuned... Global Google Code Jam 2006 - 秋に開催?'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-115289919359841472</id><published>2006-06-26T00:30:00.000+09:00</published><updated>2006-10-29T01:11:56.991+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM308 - はーどDP</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=9988"&gt;SRM308&lt;/a&gt; に挑戦。&lt;/p&gt;
&lt;p&gt;Division1の問題です．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6477&amp;amp;rd=9988"&gt;HuffmanDecoding&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=249043&amp;amp;rd=9988&amp;amp;pm=6477&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;200点問題。ハフマン・コードの復号化です。
悩むところはなく、いわれたとおり実装するだけです。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6475&amp;amp;rd=9988"&gt;CornersGame&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=249043&amp;amp;rd=9988&amp;amp;pm=6475&amp;amp;cr=15632820"&gt;Code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題。&lt;/p&gt;
&lt;img alt="CornersGame" src="http://static.flickr.com/61/193897137_da8b13b779_o.gif"/&gt;
&lt;p&gt;右下のコイン4つを左上に移動させる最短手順は？という問題です。
いくつか移動の条件が指定されます。
状態空間はたかだか 64 C 4 ほどですので、BFSで解けました。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6181&amp;amp;rd=9988"&gt;Wardrobe&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=249043&amp;amp;rd=9988&amp;amp;pm=6475&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;1000点問題．一見簡単そうなんですけど、この問題を解けたのはDivision1参加者319人中1人だけという超難問でした。
非常に難しい関係式を用いたDPで解けるそうです ( &lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;cr=251074&amp;amp;rd=9988&amp;amp;pm=6181"&gt;正解例&lt;/a&gt; ）。いまだに理解できていません。。。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9988&amp;amp;rm=249043"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/52/189525145_fde50c2ddf_o.png"/&gt;
&lt;p&gt;レーティングは1696-&amp;gt;1782と上昇。&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-115289919359841472?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115289919359841472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115289919359841472'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/06/srm308-dp.html' title='SRM308 - はーどDP'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-115289772672657871</id><published>2006-05-29T00:30:00.000+09:00</published><updated>2006-10-29T01:11:56.848+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM304 - 条件付確率</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=9825"&gt;SRM304&lt;/a&gt; に挑戦．実に1ヶ月半ぶりの参戦です。&lt;/p&gt;
&lt;p&gt;Division1の問題です．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6190&amp;amp;rd=9825"&gt;PolyMove&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=248766&amp;amp;rd=9825&amp;amp;pm=6190&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;300点問題．限られた条件のもとで、ポリゴンの頂点を移動させ、面積を最大化せよ、という問題です。
古典的なDPでとける問題なんですけど。。つまらないミスを（実は2つも）してしまいました。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6412&amp;amp;rd=9825"&gt;Conditional&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;450点問題．条件付確率の問題です。
十分解けるレベルの問題だったのに、題意をひとつ勘違いしていて、いつまでたってもExample Caseに通らず。。。結局、Submitできませんでした。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6137&amp;amp;rd=9825"&gt;TheXGame&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．Openできませんでした。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9825&amp;amp;rm=248766"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/67/189512705_850c0d10c2_o.png"/&gt;
&lt;p&gt;チャレンジも成功2、失敗4で、差し引きゼロ。結果ポイントゼロでした。。
レーティングは1775-&amp;gt;1696と大幅低下。&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-115289772672657871?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115289772672657871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/115289772672657871'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/05/srm304.html' title='SRM304 - 条件付確率'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-114718377259229629</id><published>2006-05-07T23:30:00.000+09:00</published><updated>2006-10-29T01:11:56.315+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>2006 TopCoder Open Final Round</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/tc?module=Static&amp;amp;d1=tournaments&amp;amp;d2=tco06&amp;amp;d3=alg_description"&gt;2006 TopCoder Open - Algorithm Competition&lt;/a&gt; の決勝戦が行われました。オンライン・ラウンドを勝ち抜けた48人が、ラスベガス・アラジンホテルに招待されオンサイトで5/3-5/5の3日間にわたり戦いを繰り広げました。
最後に勝ち残った8名による決勝戦の模様は通常のTopCoderのアリーナ上でリアルタイムで見ることができました。
といっても、ライブ映像が流れていたわけではなくて、こんな感じで&lt;/p&gt;
&lt;img alt="http://static.flickr.com/44/143378605_08950cdd11_o.png" src="http://static.flickr.com/44/143378605_08950cdd11_o.png"/&gt;
&lt;p&gt;競技者が行っている「問題をOpen」「コンパイル」「テスト」「コードを提出」等の行動をリアルタイムで知ることができたわけです。問題の内容や各競技者が提出したコードもリアルタイムで見ることができました。
アリーナ上では見学者が集まって、それを見ながら「あーだこーだ」いって楽しんでいます。&lt;/p&gt;
&lt;p&gt;Finalに残ったのは以下の8名。&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;tomek : ポーランド・Purdue大学。現在TopCoderでレーティングトップ。優勝候補の最右翼。&lt;/li&gt;
&lt;li&gt;Petr : ロシア・モスクワ大学。TopCoderでは珍しいC#使い。数々のプログラミングコンテストで名を残しているそうです。Google Code Jam 2005でも3位に入っています。いつも綺麗な読みやすいコードを書いてくれるので、参考になります。&lt;/li&gt;
&lt;li&gt;misof : スロバキア・Comenius大学。&lt;/li&gt;
&lt;li&gt;John Dethridge: オーストラリア・メルボルン大学。&lt;/li&gt;
&lt;li&gt;andrewzta: ロシア。&lt;/li&gt;
&lt;li&gt;cyfra: ポーランド・ワルシャワ大学。&lt;/li&gt;
&lt;li&gt;natori : 上位陣には珍しいJava使い。日本人です。&lt;/li&gt;
&lt;li&gt;fuwenjie: 中国・TsingHua大学。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;蒼々たる面子です。。ホスト国のUS勢はひとりもFinalに残れなかったのか。。
問題セットはFinalにふさわしく通常のSRMよりもはるかに難しいものばかりそろっています。&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;実況開始！&lt;/h2&gt;
&lt;p&gt;250点問題は比較的容易だったらしく、ほとんどの競技者はそれほど苦労せずにSubmit。
500点問題もfuwenjie, Petr, tomekと続々とSubmit。
こんな感じでリアルタイムに問題と提出されたコードを見ることができました。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/51/143382049_7fb44ec2fd_o.png" src="http://static.flickr.com/51/143382049_7fb44ec2fd_o.png"/&gt;
&lt;p&gt;優勝するには1000点問題を解く必要がある雰囲気が漂いはじめました。
そんな中残り時間26分でtomekが1000点問題を提出！&lt;/p&gt;
&lt;img alt="http://static.flickr.com/54/143380229_903b8124f2_o.png" src="http://static.flickr.com/54/143380229_903b8124f2_o.png"/&gt;
&lt;p&gt;この時点でトップに立ちます。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/48/143380591_980e98ef5c_o.png" src="http://static.flickr.com/48/143380591_980e98ef5c_o.png"/&gt;
&lt;p&gt;Petrが続きます。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/49/143383228_bb6a895f46_o.png" src="http://static.flickr.com/49/143383228_bb6a895f46_o.png"/&gt;
&lt;p&gt;Petr人気者です。「go Petr!!!」&lt;/p&gt;
&lt;img alt="http://static.flickr.com/47/143383770_5dc1fffed3_o.png" src="http://static.flickr.com/47/143383770_5dc1fffed3_o.png"/&gt;
&lt;p&gt;見学者たちは、「tomekの1000点理解できねー。」「tomekのはgreedy algorithmだ」「Petrのはよさそうだ」とわいわいチャットしてました。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/48/143384405_45218e28b4_o.png" src="http://static.flickr.com/48/143384405_45218e28b4_o.png"/&gt;
&lt;p&gt;Petrの1k(1000点問題）を見てみましたが、binary searchを使用しています。。。この問題からbinary searchを思いつくとは。。その発想がすごい。。
そうこういってるうちに、なんとnatoriが1kを提出！&lt;/p&gt;
&lt;img alt="http://static.flickr.com/54/143386042_389c1b9fcf_o.png" src="http://static.flickr.com/54/143386042_389c1b9fcf_o.png"/&gt;
&lt;p&gt;Petr残り5分というところで、500点問題を再提出。。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/55/143387190_d16a5b2c2c_o.png" src="http://static.flickr.com/55/143387190_d16a5b2c2c_o.png"/&gt;
&lt;p&gt;コーディング・フェーズ終了。現時点での順位はこのとおり。natoriがトップ。tomek、Petrが続きます。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/52/143387588_cb6ad21779_o.png" src="http://static.flickr.com/52/143387588_cb6ad21779_o.png"/&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;チャレンジ・フェーズ&lt;/h2&gt;
&lt;p&gt;5分間の休憩後、チャレンジ・フェーズの始まりです。
Petr開始直後に立て続けに500点問題で3つ撃破！！いっきょにもりあがります。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/46/143388256_b99595593f_o.png" src="http://static.flickr.com/46/143388256_b99595593f_o.png"/&gt;
&lt;p&gt;tomekとnatoriの1kも撃墜されました。チャレンジ・フェーズ終了時点でPetrがトップにたちます。&lt;/p&gt;
&lt;img alt="http://static.flickr.com/49/143389107_eea870cfaa_o.png" src="http://static.flickr.com/49/143389107_eea870cfaa_o.png"/&gt;
&lt;p&gt;いよいよ、あとはシステム・テストの結果まちです。。。。&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;img alt="http://static.flickr.com/50/143390301_a35d55d1fe_o.png" src="http://static.flickr.com/50/143390301_a35d55d1fe_o.png"/&gt;
&lt;p&gt;見事、Petrが栄冠に輝きました。賞金2万ドルGetです。。おめでとう！！
結局1kに正解したのはPetrだけでしたね。Petrの1kは&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Binary Search&lt;/li&gt;
&lt;li&gt;SortしてからGreedy&lt;/li&gt;
&lt;li&gt;union-find&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;と基本的なアルゴリズムの組み合わせって感じですね。見事です。。。&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-114718377259229629?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114718377259229629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114718377259229629'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/05/2006-topcoder-open-final-round.html' title='2006 TopCoder Open Final Round'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-114492519868029050</id><published>2006-04-13T00:30:00.000+09:00</published><updated>2006-10-29T01:11:54.623+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM298 - ひとふで書き</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=9819"&gt;SRM298&lt;/a&gt; に挑戦．&lt;/p&gt;
&lt;p&gt;Division1の問題です．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6160&amp;amp;rd=9819"&gt;FibonacciPositioning&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=248284&amp;amp;rd=9819&amp;amp;pm=6160&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
フィボナッチ数列に関する問題ですが，なにも考えず実装して終わりです．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6157&amp;amp;rd=9819"&gt;OrderDoesMatter&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=248284&amp;amp;rd=9819&amp;amp;pm=6157&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．
行列が複数個あるとします．
それぞれの行と列のサイズが与えられます．たとえば，以下の3個の行列が与えられたとします．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A = 7 x 3, B = 3 x 7, C = 3 x 3&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これら行列を全て使用して掛け算を行い，最終的にできる行列の行と列をかけたものの最大値を求めなさい．
という問題です.
たとえば，このケースなら&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A * C * B = (7x3) * (3x3) * (3x7) = (7x7)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;で，49が最大です．
全て使用した掛け算ができない場合は，-1を返します．たとえば&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A = 3 x 5, B = 5 x 2, C = 5 x 4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;だと，全て使用した掛け算ができないので，-1が答えになります．&lt;/p&gt;
&lt;p&gt;．．．うーん，間違って解いてしまいました．
bipertite matchigでいけると思ったのですけど，私のコードでは，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A = 1 x 2, B = 2 x 1, C = 3 x 4, D = 4 x 3&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;のようなケースでも，-1を返しません．．根本的に間違っていました.&lt;/p&gt;
&lt;p&gt;これは，有向グラフを一筆書きできるかどうかって問題に落ち着くんですよね．
グラフ理論的には， &lt;a class="reference" href="http://mathworld.wolfram.com/EulerPath.html"&gt;Euler Path&lt;/a&gt; というそうです．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6158&amp;amp;rd=9819"&gt;CountingCommonSubsequences&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
長さが50以下の文字列が3つ与えられます．
この3つの文字列に対して，共通するユニークなsubsequenceの数を求めなさい．という問題です.&lt;/p&gt;
&lt;p&gt;subsequenceとは，文字列から任意個の文字を取り除いてできる残りの文字列です．&lt;/p&gt;
&lt;p&gt;たとえば，"call"，"accelerate"，"candle"ならば，答えは6です．
"c", "a", "l", "al", "ca" ,"cl"が共通するsubsequenceです．&lt;/p&gt;
&lt;p&gt;ちなみに，&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;"aabbaabbaabbaabbaabbaabbaabbaabbaabbaabbaabb"&lt;/li&gt;
&lt;li&gt;"abababababababababababababababababababab"&lt;/li&gt;
&lt;li&gt;"aaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbb"&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;なら，答えは，1725660です．&lt;/p&gt;
&lt;p&gt;30分ほど考えたんですが，できませんでした．
SRM後に書いてみました.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public class CountingCommonSubsequences {
  char[] s1;
  char[] s2;
  char[] s3;
  int N = 50;
  long[][][] memo = new long[N][N][N];
  public long countCommonSubsequences(String a, String b, String c) {
      this.s1 = a.toCharArray();
      this.s2 = b.toCharArray();
      this.s3 = c.toCharArray();
      for (int i = 0; i &amp;lt; N; i++) {
          for (int j = 0; j &amp;lt; N; j++) {
              Arrays.fill(memo[i][j], -1);
          }
      }
      return count(0, 0, 0);
  }

  long count(int n1, int n2, int n3) {
      if (n1 &amp;gt;= s1.length || n2 &amp;gt;= s2.length || n3 &amp;gt;= s3.length) return 0;
      if (memo[n1][n2][n3] != -1) return memo[n1][n2][n3];

      long res = 0;

      nextchar:
      for (char c = 'a'; c &amp;lt;= 'z'; c++) {
          for (int i = n1; i &amp;lt; s1.length; i++) if (s1[i] == c) {
              for (int j = n2; j &amp;lt; s2.length; j++) if (s2[j] == c) {
                  for (int k = n3; k &amp;lt; s3.length; k++) if (s3[k] == c) {
                      res += 1 + count(i+1, j+1, k+1);
                      continue nextchar;
                  }
              }
          }
      }
      return memo[n1][n2][n3] = res;
  }
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9819&amp;amp;rm=248284"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/44/127863126_219dc42588_o.png"/&gt;
&lt;p&gt;今日は，だめだめでしたね．．
レーティングは，1789-&amp;gt;1775とやや低下．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-114492519868029050?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114492519868029050'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114492519868029050'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/04/srm298.html' title='SRM298 - ひとふで書き'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-114364852404241672</id><published>2006-03-27T00:30:00.000+09:00</published><updated>2006-10-29T01:11:54.553+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM293 - ビンゴ!</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=9814"&gt;SRM293&lt;/a&gt; に挑戦．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6116&amp;amp;rd=9814"&gt;ScrabbleBet&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247899&amp;amp;rd=9814&amp;amp;pm=6116&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;300点問題．
確率計算の問題です．
セオリーどおりに組み合わせの数を求めて計算してもよいですし，
DP的に解いてもいいです．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4499&amp;amp;rd=9814"&gt;Bingo&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247899&amp;amp;rd=9814&amp;amp;pm=4499&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;450点問題．
いわゆる5x5のビンゴのシミュレーションです．
アルゴリズム的に悩むところはまったくなく，ただ単に実装にちょっと手間がかかってしまう問題です．
参加者の間ではこの手の問題はあまり人気がありません．
例のごとく目いっぱい時間がかかってしまいました．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5877&amp;amp;rd=9814"&gt;CirclesOfDestruction&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
SRM中はオープンしませんでした．
SRM後に，挑戦してみました．いい問題ですね．．&lt;/p&gt;
&lt;p&gt;問題を解くアイデア自体はすぐに思い浮かびました．
「自分のスタート地点」と「円の中心」の垂直2等分線がちょうどOKな地域とNGの地域の境目になります．
これでゴール地点の候補が絞れるので，条件を満たすゴール地点のうち距離が一番短いものを返せばよいです．&lt;/p&gt;
&lt;p&gt;なんとか自力で解けましたが，やはり時間がかかってしまいました．
とてもSRM本番では時間がたらなそうです．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9814&amp;amp;rm=247899"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/46/119843209_7e198f2c59_o.png"/&gt;
&lt;p&gt;レーティングは，1730-&amp;gt;1789と少し上昇しました．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;全体的に時間かけすぎなので，今後上を狙うにはもう少しスピードアップが必要か．．
まあでもしばらくは，あまりスピードは意識せずのんびりとやっていきたいと．．&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-114364852404241672?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114364852404241672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114364852404241672'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/03/srm293.html' title='SRM293 - ビンゴ!'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-114156204096010699</id><published>2006-03-05T21:33:00.000+09:00</published><updated>2006-10-29T01:11:54.488+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>2006 TopCoder Open - Round1 撃墜</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=9917"&gt;2006 TopCoder Open - Round1&lt;/a&gt; に挑戦．
750名から400名へふるい落とされます．
予選と違い，Round1以降は，通常のSRMと同様の形式です．
チャレンジ・フェーズもあります．&lt;/p&gt;
&lt;p&gt;ラウンドへの登録時，アンケートがありました．
「コンタクト先をスポンサーであるNSA(National Security Agency)に教えてもいいかい？」
というものでした．
TopCoderはいい就職・転職の機会の場になってますね．
実際には，NSAはUS市民でないと勤務できないそうですが．．．&lt;/p&gt;
&lt;p&gt;ラウンド本番中，ちょっとした運営側の不手際がありました．
350点問題を開くと，実際には500点問題が，
500点問題を開くと，実際には350点問題が表示されてしまっていたようです．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6054&amp;amp;rd=9917"&gt;FirstToLast&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247796&amp;amp;rd=9917&amp;amp;pm=6054&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．最初にOpenした問題です．本番中はこれが350点問題だと思っていました．．&lt;/p&gt;
&lt;p&gt;整数 p, q (1 &amp;lt;= p &amp;lt;= 100, 1 &amp;lt;= q &amp;lt;= 100) が与えられます.
このとき，以下の条件を満たす正の整数 a を （存在しない場合は-1 を）返しなさい という問題です．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;a の各桁を左に回転シフトした結果を a&lt;sub&gt;rotate&lt;/sub&gt; とすると， a * p/q = a&lt;sub&gt;rotate&lt;/sub&gt;&lt;/li&gt;
&lt;li&gt;a &amp;lt; 2,000,000,000 (2 billionです．)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;条件を満たす a が複数ある場合は，そのうちもっとも小さいものを返します．
たとえば，p = 1, q = 4 ならば，答えは a = 102564 になります．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;"102564" の左端の1 を右にくっつけて， a&lt;sub&gt;rotate&lt;/sub&gt; = 25641&lt;/li&gt;
&lt;li&gt;a * p / q = 102564 * 1/ 4 = 25641 = a&lt;sub&gt;rotate&lt;/sub&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ですね．&lt;/p&gt;
&lt;p&gt;うーん方針が浮かびませんでした．
とりあえずExample Case に通るようにしてからSubmitしました．
不完全だというのはわかっていましたが，もうあきらめて次の問題に移りました．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6095&amp;amp;rd=9917"&gt;SeparateConnections&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247796&amp;amp;rd=9917&amp;amp;pm=6095&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;実は，こっちが，350点問題でした．本番中は，500点問題だと思って取り組んでいました．&lt;/p&gt;
&lt;p&gt;ノードがn個与えられます．各ノード間が通信可能かどうがが，マトリックス形式で与えられます．&lt;/p&gt;
&lt;p&gt;ノードが5個の場合です．Yが通信可能．Nは通信不可能です．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"NYYYY",
"YNNNN",
"YNNNY",
"YNNNY",
"YNYYN"
&lt;/pre&gt;
&lt;p&gt;各ノードは同時に1つの他のノードと通信できるとします．2つ以上とは通信できません．
この場合，お互いに通信しているノードのペアを最大いくつ作成できるか？
その通信しているノード数（ペア数 x 2 になります）を求めなさいという問題です．&lt;/p&gt;
&lt;p&gt;本番中は，思いっきり問題を勘違いしてしまって，Bipertite Matching を使用して解いてしまいました．
普通にDPで解くべき問題でした．こんな感じになります．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public class SeparateConnections {

  public int howMany(String[] mat) {
      int N = mat.length;
      int max = 0;
      boolean[] ok = new boolean[1&amp;lt;&amp;lt;N];
      ok[0] = true;
      for (int i = 0; i &amp;lt; (1&amp;lt;&amp;lt;N); i++) {
          if (!ok[i]) continue;
          max = Math.max(max, Integer.bitCount(i));
          for (int n1 = 0; n1 &amp;lt; N; n1++) {
              for (int n2 = n1+1; n2 &amp;lt; N; n2++) {
                  if ( mat[n1].charAt(n2) == 'Y'
                          &amp;amp;&amp;amp; (i &amp;amp; (1 &amp;lt;&amp;lt; n1)) == 0
                          &amp;amp;&amp;amp; (i &amp;amp; (1 &amp;lt;&amp;lt; n2)) == 0) {
                      ok[ i | (1 &amp;lt;&amp;lt; n1) | (1 &amp;lt;&amp;lt; n2)] = true;
                  }
              }
          }
      }
      return max;
  }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6052&amp;amp;rd=9917"&gt;NumPermutationOrders&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．ていうか無理．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9917&amp;amp;rm=247796"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/40/108055384_109a3de959_o.png"/&gt;
&lt;p&gt;スコア0です．．．敗退決定です．
スコア0は，401位でした．
1点でもスコアがあったら，400位以内に入っていたようです．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;あー勘違い．&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-114156204096010699?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114156204096010699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114156204096010699'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/03/2006-topcoder-open-round1.html' title='2006 TopCoder Open - Round1 撃墜'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-114145861514685366</id><published>2006-03-03T23:30:00.001+09:00</published><updated>2006-10-29T01:11:54.413+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>2006 TopCoder Open - Odds発表</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;予選通過のお知らせメールがきました．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello gentoo,&lt;/p&gt;
&lt;p&gt;Congratulations!  The results of the Qualification Round of the 2006 TopCoder(R) Open, Sponsored by AMD, are official.  You have advanced into Round #1, which will take place on Saturday, March 4 at Noon EST (GMT -5).  Registration opens at 9:00am and closes at 11:55am EST.  All participants in Round #1 will win a 2006 TCO t-shirt.&lt;/p&gt;
&lt;p&gt;...&lt;/p&gt;
&lt;p&gt;Congratulations again.  And, as always, best of luck to you in the Arena!&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The TopCoder Competitions Team&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Webサイトにも， &lt;a class="reference" href="http://www.topcoder.com/tc?module=SimpleStats&amp;amp;d1=tournaments&amp;amp;d2=tco06&amp;amp;d3=alg_qualification&amp;amp;c=tco06_alg_qual&amp;amp;trans=true"&gt;予選通過者の一覧&lt;/a&gt; が発表されていました．&lt;/p&gt;
&lt;p&gt;で，面白いものを発見しました．
予選通過者の，レーティングと変動率(Volatility) をもとにした， &lt;a class="reference" href="http://www.logicgamesonline.com/jdmetz/topcoder/tco2006/TCO2006_Round1.html"&gt;オッズ&lt;/a&gt; の一覧です．
モンテカルロ・シミュレーションにより値を計算しているそうです．&lt;/p&gt;
&lt;img alt="http://static.flickr.com/37/107507785_848022c1d8_o.png" src="http://static.flickr.com/37/107507785_848022c1d8_o.png"/&gt;
&lt;p&gt;こういう盛り上げ方はうまいですね．．ちなみに私は，&lt;/p&gt;
&lt;img alt="http://static.flickr.com/54/107507797_4626959f91_o.png" src="http://static.flickr.com/54/107507797_4626959f91_o.png"/&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Round1通過: 57.28%&lt;/li&gt;
&lt;li&gt;Round2通過: 17.12%&lt;/li&gt;
&lt;li&gt;Round3通過: 2.41%&lt;/li&gt;
&lt;li&gt;Round4通過: 0.11%&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;と予想されています．
ラスベガスにいける確率は，0.11%ってことですね．．&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-114145861514685366?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114145861514685366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114145861514685366'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/03/2006-topcoder-open-odds.html' title='2006 TopCoder Open - Odds発表'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-114145530603255156</id><published>2006-03-02T23:30:00.000+09:00</published><updated>2006-10-29T01:11:54.262+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>2006 TopCoder Open Qualification Round</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/tc?module=Static&amp;amp;d1=tournaments&amp;amp;d2=tco06&amp;amp;d3=alg_description"&gt;2006 TopCoder Open - Algorithm Competition&lt;/a&gt; - の予選 (Qualification Round)に挑戦です．
いよいよ，始まりました．
TopCoder Open はTopCoder の "Crown of Jewels" ．
一番，盛り上がるイベント・お祭りだそうです．&lt;/p&gt;
&lt;p&gt;予選を通過できるのは750名．
普段のレーティングが上位の100名は，自動的に予選を免除されますので，
残された650の椅子を巡る戦いです．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;予選 (Qualification Round): 750名通過&lt;/li&gt;
&lt;li&gt;Round1: 750名 -&amp;gt; 400名&lt;/li&gt;
&lt;li&gt;Round2: 400名 -&amp;gt; 200名&lt;/li&gt;
&lt;li&gt;Round3: 200名 -&amp;gt; 100名&lt;/li&gt;
&lt;li&gt;Round4: 100名 -&amp;gt; 48名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;見事，Round4を勝ち抜いた48名は，ラスベガスにご招待され，オンサイトで決勝です．&lt;/p&gt;
&lt;p&gt;通常のSRMと異なり，予選はちょっと形式が異なります．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;問題は2問，制限時間は1時間&lt;/li&gt;
&lt;li&gt;開始時間は決まっていない．24時間以内ならいつ挑戦をはじめてもよい&lt;/li&gt;
&lt;li&gt;チャレンジ・フェーズはなし&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;問題セットは，5種類用意され，そのうちどれか1種類が自動的にアサインされます．
各問題セットから，上位 (650/5 =) 130 名が予選を通過できます．
早速，アリーナに参加してみると&lt;/p&gt;
&lt;img alt="http://static.flickr.com/44/107444859_1a8ad71a24_o.png" src="http://static.flickr.com/44/107444859_1a8ad71a24_o.png"/&gt;
&lt;p&gt;Set14にアサインされました．
問題1種類につき，Roomが3つ用意されていますね．
計15Roomです．&lt;/p&gt;
&lt;img alt="http://static.flickr.com/43/107444871_c1ceae571b_o.png" src="http://static.flickr.com/43/107444871_c1ceae571b_o.png"/&gt;
&lt;p&gt;各Roomごとに，およそ170名ほど割り振られていました．
ということは，参加者の総数は 170 x 15 = 2550 名ほどか．&lt;/p&gt;
&lt;p&gt;予選通過のためには各Room 内で，130 /3 = 43 位 くらいに入るのが目安になるか．
自分が挑戦した時間が終了近かったので，もうすでに終わっている人のスコアをあらかじめみることができました．
自分がアサインされたRoom14では，こんな様子でした．&lt;/p&gt;
&lt;img alt="http://static.flickr.com/44/107444874_3d04bb2d57_o.png" src="http://static.flickr.com/44/107444874_3d04bb2d57_o.png"/&gt;
&lt;p&gt;なるほど，ボーダーラインの43位に入るためには，2問とも確実に，その上ある程度スピードも要求されそうです．
まだシステムテストは終わっていないから，ボーダーはこれより下がるでしょうが，思っていたより，レベルが高そう．．
それとも問題が簡単なのか？．．&lt;/p&gt;
&lt;p&gt;と思いつつ，自分もスタート．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6105&amp;amp;rd=9903"&gt;SlowKeyboard&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247765&amp;amp;rd=9903&amp;amp;pm=6105&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．問題の意味をつかむのに，一苦労．&lt;/p&gt;
&lt;p&gt;結局，Brute Force で全パターンを調べました．
この時点で，18分ほど時間をとられました．まずい．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4662&amp;amp;rd=9903"&gt;DigitFilter&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247765&amp;amp;rd=9903&amp;amp;pm=4662&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;750点問題．&lt;/p&gt;
&lt;p&gt;数字が与えられます．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;k = "12XX355"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Xのところは判明しない桁です．
この数字kが(num)で割り切れるとした場合，このような数字kは何通りありますか？
という問題です.たとえば，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;k = "1X"，num=3&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ならば，"12", "15", "18" の3通りです．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;k = "23X34XX24XX34X", num=17&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ならば，58823通りです．&lt;/p&gt;
&lt;p&gt;DPでいけると思い，方針じたいは結構早めに決まったのですが，実装にとまどる，とまどる．
あせっていたのか．．結局，30分ほどかかり，Submit．&lt;/p&gt;
&lt;p&gt;2問あわせてスコアは536.71．
Room14内で，65位ほどでした．．これはだめか．．&lt;/p&gt;
&lt;img alt="http://static.flickr.com/38/107444883_c25d968b87_o.png" src="http://static.flickr.com/38/107444883_c25d968b87_o.png"/&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;最終的なシステムテストの結果です．( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9903&amp;amp;rm=247765"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;Room7/9/14 は同じ問題セットだったそうです．そのRoom7/9/14をあわせた中での順位は，&lt;/p&gt;
&lt;img alt="http://static.flickr.com/52/107444885_2ff125b400_o.png" src="http://static.flickr.com/52/107444885_2ff125b400_o.png"/&gt;
&lt;p&gt;85位．130位以内なので，予選通過ですよね？ まだ正式連絡はきていないけれど．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Room14だけ，なぜかハイスコアの人が多かったこと&lt;/li&gt;
&lt;li&gt;750点問題に落ちた人が，相当多かった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということで，85位に入り込めたっぽいですね．&lt;/p&gt;
&lt;p&gt;750点問題で落ちた人は，可能な数字をすべて生成してから，それらをnumで割り切れるかどうかをチェックしている人が多かったようです．
kの最大の長さの条件は18ですので，k = "XXXXXXXXXXXXXXXXXX" の場合，
必要な数字は10^18通りになってしまいます．
これを全て調べるのは，絶対無理ですね．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;もっと正確かつ早い実装力が必要．．&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-114145530603255156?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114145530603255156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114145530603255156'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/03/2006-topcoder-open-qualification-round.html' title='2006 TopCoder Open Qualification Round'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-114092929748001966</id><published>2006-02-23T00:30:00.001+09:00</published><updated>2006-10-29T01:11:54.179+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM291 - OutOfMemory</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=9812"&gt;SRM291&lt;/a&gt; に挑戦．&lt;/p&gt;
&lt;p&gt;2006 TopCoder Open - Algorithm Competition が来週の2月28日から始まります．
今日は，それに向けて最後のSRMになります．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6072&amp;amp;rd=9812"&gt;Snowflakes&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247699&amp;amp;rd=9812&amp;amp;pm=6072&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
折り紙で雪の結晶をつくりましょう．&lt;/p&gt;
&lt;img alt="SRM291 Snowflakes From TopCoder" src="http://www.topcoder.com/contest/problem/Snowflakes/snowflakefinal.gif"/&gt;
&lt;p&gt;このように8等分に折った折り紙に対して，&lt;/p&gt;
&lt;img alt="SRM291 Snowflakes From TopCoder" src="http://www.topcoder.com/contest/problem/Snowflakes/snowflake5.gif"/&gt;
&lt;p&gt;穴をあけてから，もとの大きさに広げると，あら不思議．
雪の結晶のように，対称な，きれいな形ができますねー．
あ，そう．って感じですが，，，&lt;/p&gt;
&lt;p&gt;問題は，以下のような，8等分に折った折り紙の穴のパターンが与えられたとき，&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{"*",
 "..",
 ".*.",
 ".**.",
 ".*.**"}
&lt;/pre&gt;
&lt;p&gt;広げた形のパターンを求めてください．という問題です.
例の場合は，答えはこのようになります．:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{"**.*..*.**",
 "*.**..**.*",
 ".*.*..*.*.",
 "***....***",
 "....**....",
 "....**....",
 "***....***",
 ".*.*..*.*.",
 "*.**..**.*",
 "**.*..*.**" }
&lt;/pre&gt;
&lt;p&gt;悩むところは特にないですが，いかに時間をかけないでサクサクすませられるか勝負です．
私は，14分もかかってしまいましたが，早い人は，3分かからずにすませています．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6071&amp;amp;rd=9812"&gt;CrazySwitches&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247699&amp;amp;rd=9812&amp;amp;pm=6071&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．
素直にBFSでいけました．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5954&amp;amp;rd=9812"&gt;StickedWords&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
Level1，Level2問題を終えた時点で，30分ほど時間がありましたので，1000点問題にチャレンジ．&lt;/p&gt;
&lt;p&gt;単語(Word)がいくつか与えられます．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;{"salad", "sandwich", "hamburger", "rings"}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これらの単語の最初の文字と最後の文字をつなげて，文字列をつくっていきます．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"hamburgeringsandwichamburger..."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「しりとり」ですね．こうしてできる文字列のうち，長さが (len) 以上のもので，
辞書的に一番最初にくる文字列を返しなさい．という問題です．
たとえば，入力が&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{"abd", "dgga", "abdg", "gga", "gg", "gaader"}
len: 22
&lt;/pre&gt;
&lt;p&gt;ならば，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"abdggabdggabdggabdgaader"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;が答えになります．&lt;/p&gt;
&lt;p&gt;ちょっと考え，「DPでいける！」と思い，コーディング開始.
1000点問題 をはじめて解けるか？！ と思ったのですが，時間が足りませんでした．．
SRM後，悔しいので完成させました．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public class StickedWords {

  public String constructLine(String[] dict, int len) {

      String[][] dp = new String[len+51][26];
      for (int i = 1; i &amp;lt; dp.length; i++) {
          for (int j = 0; j &amp;lt; 26; j++) {
              for (String word : dict) {
                  if (word.charAt(word.length()-1) - 'a' != j) continue;
                  if (i == word.length()) {
                      if (dp[i][j] == null || word.compareTo(dp[i][j]) &amp;lt; 0) {
                          dp[i][j] = word;
                      }
                      continue;
                  }
                  int pre = i - (word.length() - 1);
                  if (pre &amp;lt;= 0) continue;
                  int first = word.charAt(0) - 'a';
                  if (dp[pre][first] == null) continue;
                  String next = dp[pre][first] + word.substring(1);
                  if (dp[i][j] == null || next.compareTo(dp[i][j]) &amp;lt; 0) {
                      dp[i][j] = next;
                  }
              }
          }
      }
      String res = null;
      for (int i = len; i &amp;lt; len+51; i++) {
          for (int j = 0; j &amp;lt; 26; j++) {
              if (dp[i][j] == null) continue;
              if (res == null || dp[i][j].compareTo(res) &amp;lt; 0) {
                  res = dp[i][j];
              }
          }
      }
      return (res == null) ? "" : res;
  }
}
&lt;/pre&gt;
&lt;p&gt;もうちょっとだったのになーと思っていたけど，実は，ぜんぜんもうちょっとではありませんでした．
落とし穴がまっていました．．
最悪のケース (len=2500)では,&lt;/p&gt;
&lt;pre class="literal-block"&gt;
java.lang.OutOfMemoryError...
&lt;/pre&gt;
&lt;p&gt;を引き起こしてしまいます．
TopCoderでは時間（2秒以内）という制限だけではなく，使用メモリの制限 (64Mbyte)もありました．
最悪のケース (len=2500)では，最終的にはメモリ使用量は，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2500 x (2500 / 2) x 26 = 81250000&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ですから，80MByte を超えますね.．．
これはトリッキーだ．．普通，気づかないよな．．
1000点問題にしてはとっかかりやすいと思ったけど，こういう側面があったとは．．
こういうのは，問題作成者が意図的にやってるんですね．&lt;/p&gt;
&lt;p&gt;ひとつあたりの単語の長さは最大50なので，DPをしつつ，最近の50ステップ分だけ，覚えるようにして，
いらなくなったものには，null をいれると．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
}
if (i - 51 &amp;gt;= 0) {
    dp[i-51] = null;
}
&lt;/pre&gt;
&lt;p&gt;これで，なんとか System Testに通るようになります．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9812&amp;amp;rm=247699"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/27/103387512_dc267bf9ed_o.png"/&gt;
&lt;p&gt;レーティングは 1626 -&amp;gt; 1730 と100ほど上昇しました．
いよいよ来週は，2006 TopCoder Open の予選です．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;メモリ使用量に注意．&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-114092929748001966?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114092929748001966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/114092929748001966'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/02/srm291-outofmemory.html' title='SRM291 - OutOfMemory'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113911838981822210</id><published>2006-02-05T14:46:00.000+09:00</published><updated>2006-10-29T01:11:53.810+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM287 - 気分は中学生？連立２元方程式</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=9808"&gt;SRM287&lt;/a&gt; に挑戦．
1ヶ月ぶりの参戦．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6013&amp;amp;rd=9808"&gt;TwoEquations&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247545&amp;amp;rd=9808&amp;amp;pm=6013&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;300点問題．以下のような2つの文字列が与えられます．:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"1*X + 2*Y = 6"
"1*X + (-4)*Y = (-3)"
&lt;/pre&gt;
&lt;p&gt;連立2元方程式です．「中学生か俺は？」でした．．
これを解いて，解が唯一存在するならば，以下のように解を文字列で&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"X=(-7)/3 Y=3/4"
&lt;/pre&gt;
&lt;p&gt;解がないならば&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"NO SOLUTIONS"
&lt;/pre&gt;
&lt;p&gt;を，解が複数存在するならば&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"MULTIPLE SOLUTIONS"
&lt;/pre&gt;
&lt;p&gt;を返しなさい．という問題です.
250点問題ではなく300点問題ですのでちょっと面倒です．ですがそれほど難しい問題ではないと一見思ったのですが．．&lt;/p&gt;
&lt;p&gt;方針としては，各係数A1-A3, B1-B3&lt;/p&gt;
&lt;pre class="literal-block"&gt;
A1 * X + A2 * Y = A3
B1 * X + B2 * Y = B3
&lt;/pre&gt;
&lt;p&gt;をパースしてから，&lt;/p&gt;
&lt;pre class="literal-block"&gt;
int det = A1 * B2 - A2 * B1;
int x = B2 * A3 - A2 * B3;
int y = A1 * B3 - B1 * A3;
&lt;/pre&gt;
&lt;p&gt;を計算して，det == 0 ならば，「解がない」 か 「解が複数」&lt;/p&gt;
&lt;pre class="literal-block"&gt;
if (det == 0) {
    if (x == 0) {
        return "MULTIPLE SOLUTIONS";
    }
    return "NO SOLUTIONS";
}
&lt;/pre&gt;
&lt;p&gt;それ以外ならば， 「解がひとつ」ということで，&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"X=x/det Y=y/det"
&lt;/pre&gt;
&lt;p&gt;として，約分等・正しくフォーマットして返せばよい．
これでいけると思ってSubmitしたのですが，甘かったです．&lt;/p&gt;
&lt;p&gt;これだけでは，以下のような係数がゼロの場合に対処できませんでした．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
"0*X + 0*Y = 1"
"0*X + 0*Y = 2"
&lt;/pre&gt;
&lt;p&gt;この場合は，正しい正解は"NO SOLUTIONS"ですが，上記ロジックだけだと"MULTIPLE SOLUTIONS"を返してしまいます．&lt;/p&gt;
&lt;p&gt;以下のように係数ゼロを特別に扱う必要性がありました．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
if (A1 == 0 &amp;amp;&amp;amp; A2 == 0 &amp;amp;&amp;amp; A3 != 0) return "NO SOLUTIONS";
if (B1 == 0 &amp;amp;&amp;amp; B2 == 0 &amp;amp;&amp;amp; B3 != 0) return "NO SOLUTIONS";
if (A1 == 0 &amp;amp;&amp;amp; B1 == 0 &amp;amp;&amp;amp; (A2 * B3 - B2 * A3) != 0) return "NO SOLUTIONS";
if (A2 == 0 &amp;amp;&amp;amp; B2 == 0 &amp;amp;&amp;amp; (A1 * B3 - B1 * A3) != 0) return "NO SOLUTIONS";
&lt;/pre&gt;
&lt;p&gt;私も含めて多くの人はゼロのケースを考慮しないCodeを書いてしまったようです．
これに気づいた人は，チャレンジタイムで大稼ぎしていました．&lt;/p&gt;
&lt;p&gt;この問題のDivision1での正解率は11%，
同じ問題がDivision2のレベル2問題にも使用されていましたがDivision2ではなんと正解率0%，
誰ひとり正解できなかったようです．．&lt;/p&gt;
&lt;img alt="Problem Stats" src="http://static.flickr.com/25/95611480_5e4542f8c0_o.png"/&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5973&amp;amp;rd=9808"&gt;MooresLaw&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247545&amp;amp;rd=9808&amp;amp;pm=5973&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;450点問題．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「ムーアの法則」: コンピュータのスピードは，18ヶ月で2倍になる&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今，計算を始めると14年かかる問題があるとします．
今すぐ始めるのではなく，18ヶ月待ってスピードが2倍の新しいコンピュータを買ってそれで計算を始めると7年ですみます．
14年かかる計算が，合計 (1.5 + 7 = ) 8.5年ですむわけです．
この例だと，約4年まってから計算を始めるのがベストです．合計( 4 + 2.2 = ) 6.2年ですみます.&lt;/p&gt;
&lt;p&gt;このように，計算にかかる年数 (years) が与えられた場合，ムーアの法則が成り立つとすると，最短・今から何年後に計算を終わらせることができるでしょうか？という問題です．
いつ新しいコンピュータを買い計算をはじめるか？がポイントになります．&lt;/p&gt;
&lt;p&gt;x年後に，新しいコンピュータを買って計算を始めるとすると，トータルでは&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;y = x +  (years / 2^(x / 1.5) )&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;かかることになります．このyが最小になるxを探せばよいことになります．
数学的に解くことはできるのでしょうが（微分してゼロになるところを求める）．．
数学的に悩むよりは，このようなU字型の関数の場合は，
いわゆるbinary searchではなく，ternary search で，yが最小になるxを探すことができます．&lt;/p&gt;
&lt;img alt="ternary search" src="http://static.flickr.com/38/95712324_5b626917dd_o.png"/&gt;
&lt;p&gt;区間 ( [left, right] ) 内の2点(x1, x2)をとり，y1, y2 を計算して，&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;y1 &amp;gt; y2 ならば，left = x1&lt;/li&gt;
&lt;li&gt;y1 &amp;lt; y2 ならば，right = x2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;として，区間を狭めていけば，最終的には，最小のyをとるxaにたどり着きます.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public class MooresLaw {

  public double shortestComputationTime(int years) {

      double left = 0;
      double right = years;

      while (right - left &amp;gt; 1e-11) {
          double x1 = (left * 2 + right) / 3.0;
          double x2 = (left + right * 2) / 3.0;
          if (cal(x1, years) &amp;gt; cal(x2, years)) {
              left = x1;
          } else {
              right = x2;
          }
      }
      return cal(right, years);
  }

  double cal(double x, int years) {
      return x + years / Math.pow(2, x / 1.5);
  }
&lt;/pre&gt;
&lt;p&gt;SRM中は，x年後のコンピュータのスピードが，Math.pow(2, x / 1.5) で表せることにきずかず，
前半部分・回りくどいことをしていまいました．．．
なんとか正解しましたが．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=6005&amp;amp;rd=9808"&gt;CoinGame&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
Openしたものの，手が出ず．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=9808&amp;amp;rm=247545"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/41/95603073_48fb4a2290_o.png"/&gt;
&lt;p&gt;全体的にポイントが低かったためか，レーティングは 1542 -&amp;gt; 1626 と上昇しました．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113911838981822210?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113911838981822210'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113911838981822210'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/02/srm287.html' title='SRM287 - 気分は中学生？連立２元方程式'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113663528106008641</id><published>2006-01-07T00:30:00.000+09:00</published><updated>2006-10-29T01:11:53.722+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM281 - 2006年はポイントゼロスタート</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8078"&gt;SRM281&lt;/a&gt; に挑戦．今年，最初のSRMです．
例のごとく日本時間の深夜1:00スタートという，ありがたいんだが，ありがたくないんだがよくわかりませんが，やはり眠いなかでの参戦となりました．まあ，平日昼間だと参加できないので，ありがたいんでしょうが．．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5984&amp;amp;rd=8078"&gt;IntegerGenerator&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247299&amp;amp;rd=8078&amp;amp;pm=5984&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;int[] allowed: 使用が許されている数字(0-9のいずれか)のリスト&lt;/li&gt;
&lt;li&gt;String current: 現在の数 (整数)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;が与えられます．この時，&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;与えられた数 currentの各桁が 許可数字だけを使用しているかどうかをチェック&lt;/li&gt;
&lt;li&gt;1がOKなら，許可数字だけを使用して currentより大きい次の数字を生成して返しなさい&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;という問題です．
たとえば，&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;allowed: {1, 2, 3}&lt;/li&gt;
&lt;li&gt;current:  "2133"&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ならば，current: 2133 の各桁は，許可数字{1, 2, 3}に含まれているものだけを使用しているのでOKです．
また，currentより大きい，許可数字だけを使用した次の数は，"2211" になります．&lt;/p&gt;
&lt;p&gt;最初は，ただ単にcurrentを1ずつincrementしてOKかどうかチェックするという単純な方法で十分と思い込み，8分ほどでSubmitしました．
Submit後に，いくつかチェックしていると，入力条件によってはこれではタイムアウトすることに気づきました．入力が&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;{9}, "9999999999" (10桁)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;でタイムアウトです．
この場合の正解は"99999999999" (11桁) ですが，1ずつincrementしていては，とてもじゃないが2秒以内には終わりません．&lt;/p&gt;
&lt;p&gt;慌ててやり直しましたが．．．はまりました．．完全に方針を誤り右往左往でした．
最終的になんとか完成させ再提出したのですが (提出時点ではポイント75と最低点でした...），
それでもバグがひとつ入っていたため，System Testに落ちました．
入力のint配列: allowed が空 のケースで，ArrayIndexOutOfExceptionが発生させてしまっています．&lt;/p&gt;
&lt;p&gt;初歩的な入力条件のチェックミス．．空かどうかチェックを一行いれておけば，SystemTestに通っていましたね．&lt;/p&gt;
&lt;p&gt;SRM後に，冷静になって，コードを書き直してみました．
使用できる数字が限られたケースで，1を足す動作を，シミュレートするだけです．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public class IntegerGenerator {
  public String nextInteger(int[] allowed, String current) {
      Arrays.sort(allowed);
      char[] ca = current.toCharArray();
      if (ca[0] == '0') return "INVALID INPUT";
      for (char c : ca) {
          if (Arrays.binarySearch(allowed, c - '0') &amp;lt; 0) return "INVALID INPUT";
      }
      for (int i = ca.length - 1; i &amp;gt;= 0; i--) {
          int index = Arrays.binarySearch(allowed, ca[i] - '0');
          if (index == allowed.length - 1) {
              ca[i] = (char) ('0' + allowed[0]);
          } else {
              ca[i] = (char) ('0' + allowed[index + 1]);
              return new String(ca);
          }
      }
      return ((allowed[0] == 0) ? allowed[1]: allowed[0]) + new String(ca);
  }
}
&lt;/pre&gt;
&lt;p&gt;こうしてみるとそんなに難しい問題ではなかったですね．やっぱり250点問題です．
本番中は，頭が回りませんでした．．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5919&amp;amp;rd=8078"&gt;BallBouncing&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;600点問題．Openしませんでした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5949&amp;amp;rd=8078"&gt;Equidistance&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．Openしませんでした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8078&amp;amp;rm=247299"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/39/83328489_144104161d_o.png"/&gt;
&lt;p&gt;今日は，惨敗です．
チャレンジタイムも，ターゲットが次々とほかの人にさらわれてしまい，結局，チャレンジ ゼロでした．．&lt;/p&gt;
&lt;p&gt;レーティングは 1630 -&amp;gt; 1542 と，100近く低下しました．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;当たり前ですが，入力条件をよく読むように．&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113663528106008641?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113663528106008641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113663528106008641'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2006/01/srm281-2006.html' title='SRM281 - 2006年はポイントゼロスタート'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113614745545986218</id><published>2005-12-30T00:30:00.003+09:00</published><updated>2006-10-29T01:11:53.652+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM280 - Challenge祭り</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8077"&gt;SRM280&lt;/a&gt; に挑戦．
今年，最後のSRMになります．思えば今年の後半は，TopCoderで楽しませてもらいました．
いまや，2週間に一度ほどの「趣味」です．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5977&amp;amp;rd=8077"&gt;CompletingBrackets&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247258&amp;amp;rd=8077&amp;amp;pm=5977&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
" &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;]][][]][&lt;/span&gt;&lt;/tt&gt;  "のように閉じ括弧・開き括弧のみを含んだ文字列が与えられます．
この文字列の最初・または最後に，できるだけ最小限の" &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;]&lt;/span&gt;&lt;/tt&gt; "または " &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[&lt;/span&gt;&lt;/tt&gt; "を与えて，ちょうど括弧が対応するように文字列を完成させその文字列を返す問題です．
例の場合は， 最初に " &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[&lt;/span&gt;&lt;/tt&gt; "を3個，最後に" &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;]&lt;/span&gt;&lt;/tt&gt; "を1個加えた，" &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;[[[]][][]][]&lt;/span&gt;&lt;/tt&gt; "が正解になります．&lt;/p&gt;
&lt;p&gt;これまでは250点問題は，何も考えずにただ実装ということが多かったいのですが，今回は一瞬，どうしたらよいかわかりませんでした．
「まずい」と思いましたが，力任せに「うまくいくであろう」方法でなんとか仕上げました．
はっきりいって根拠なしでしたが，手元で試した限りでは，あらゆるケースで問題がなかったので，そのままSubmitしました．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5936&amp;amp;rd=8077"&gt;GridCut&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247258&amp;amp;rd=8077&amp;amp;pm=5936&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．
幅 (width) cm x 高さ (height) cm の紙 があります．
紙には，方眼紙のように1cm間隔で格子状に線が引いてあるとします．
この紙をはさみを使って，n セル だけ面積を残して切り取りたいとします．
最低，何cmはさみで紙を切る必要があるでしょうか？という問題です．
はさみは格子状の線に沿ってしか使用できません．ななめにきってはだめです．&lt;/p&gt;
&lt;img alt="SRM280 GridCut From TopCoder" src="http://static.flickr.com/61/193898525_7f130a569d_o.png"/&gt;
&lt;p&gt;図のような，5 x 10 の紙の場合，&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;10セルだけ残すときは，左の赤のラインが最小の長さです．答えは5&lt;/li&gt;
&lt;li&gt;18セルだけ残すときは，左の緑のラインが最小の長さです．答えは6&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;アルゴリズムの知識というよりは，論理的思考力を問われる問題です．
いわゆる小学生でもその気になれば解ける問題です．
散々，悩んだあげく，とりあえず提出しました．&lt;/p&gt;
&lt;p&gt;．．ですが，Level 3 問題があまりに手がでなかったのであきらめて，Level2問題を見直していたところ，バグにきずいて，再提出しました．
再提出するとポイントは30%のペナルティが与えられます．&lt;/p&gt;
&lt;p&gt;「n」 セル残す というのは，「 width * height - n 」セル残すということと同じことなんですね．．．
それをまったく考慮していなかったため，それに対応させました．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4846&amp;amp;rd=8077"&gt;DrawPlanar&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1100点問題．いつもの「1000点」じゃなくて，「1100点」ってだけで，もう恐ろしさ満点です．
まったくお手上げでした．
さすがに，正解できた人は，Division1 304人中3人だけでした．
(&lt;a class="reference" href="http://www.topcoder.com/tc?module=ProblemDetail&amp;amp;rd=8077&amp;amp;pm=4846"&gt;Problem Detail&lt;/a&gt;)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;今回は，チャレンジタイムでは，GridCutの問題で，(100, 100, 9001) という入力でチャレンジしまくりました．
自分がミスっていたところは，きっと他人もミスっているに違いないと勝手に思い込んで．
手当たり次第，チャレンジして，12チャレンジ，8個撃墜しました．&lt;/p&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8077&amp;amp;rm=247258"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/38/79387792_0bafbb2977_o.png"/&gt;
&lt;p&gt;チャレンジしまくった結果です．
自分も同じ問題を，チャレンジされ撃墜されたというオチまでついています．
square * (square-1) のケースを考慮していませんでした．．&lt;/p&gt;
&lt;img alt="Challeges" src="http://static.flickr.com/43/79387801_8040696132_o.png"/&gt;
&lt;p&gt;レーティングは1520 -&amp;gt; 1630 と上昇しました．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113614745545986218?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113614745545986218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113614745545986218'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/12/srm280-challenge_113614745545986218.html' title='SRM280 - Challenge祭り'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113561518668166547</id><published>2005-12-27T01:39:00.000+09:00</published><updated>2006-10-29T01:11:53.352+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM277 - 初賞金げっと</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8074"&gt;SRM277&lt;/a&gt; に挑戦．ちょうど10回目のSRMです．土曜の深夜2:00が開始時間でしたので，眠かった．．．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5870&amp;amp;rd=8074"&gt;RogersPhenomenon&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247060&amp;amp;rd=8074&amp;amp;pm=5870&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
Division1にしては比較的容易でした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4828&amp;amp;rd=8074"&gt;AirlinerSeats&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=247060&amp;amp;rd=8074&amp;amp;pm=4828&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．
飛行機内のいわゆる「通路側座席」の数が最大になるように座席を配置する問題です．
これも，500点問題にしては簡単な方だと思います．小学生でも十分できる問題です．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5918&amp;amp;rd=8074"&gt;SafeJourney&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
うーん，できませんでした．方針すら浮かびませんでした．
問題空間をコンパクト化するのがポイントだったようです．あー，なるほど．
そうすれば，十分，BFSでいけます．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8074&amp;amp;rm=247060"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/9/74680058_35c3a95993_o.png"/&gt;
&lt;p&gt;レーティングは1500台になり，イエローネームになりました．
今回でちょうど10回目のSRMでしたので，記念に，現時点の状況を残しておきます．
レーティングの推移です．&lt;/p&gt;
&lt;img alt="Rating History" src="http://static.flickr.com/43/74718339_0b2f240a32_o.png"/&gt;
&lt;p&gt;まだ，初登場時のレーティングには届いていません.&lt;/p&gt;
&lt;img alt="TopCoder Member Card" src="http://static.flickr.com/37/74728743_48def73748_o.png"/&gt;
&lt;p&gt;今回のSRMは，MSNがスポンサーで上位の人には賞金が出ます．
自分には縁がないと思っていたのですけど，後日，メールが来て&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Congratulations! The results of TopCoder SRM 277 are official.  You have
won $32.0.&lt;/p&gt;
&lt;p&gt;In order for TopCoder to release payment to you, you must complete
certain steps within 60 days of this email.  Please follow the instructions here:
&lt;a class="reference" href="http://www.topcoder.com/PactsMemberServlet?t=affidavit&amp;amp;c=affidavit_history"&gt;http://www.topcoder.com/PactsMemberServlet?t=affidavit&amp;amp;c=affidavit_history&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Unless you have previously specified otherwise, your prize money will, by default, be paid by check.  If you would like to be paid by wire transfer or PayPal, send an email to XXXXXXXXX with the details of your preferred payment method.  Remember to include your TopCoder handle in the email.&lt;/p&gt;
&lt;p&gt;Please keep in mind that you have 60 days to claim your prize.  Your prize will be forfeited if it is not claimed within 60 days.&lt;/p&gt;
&lt;p&gt;Congratulations again on your SRM performance.&lt;/p&gt;
&lt;p&gt;As always, best of luck to you in the Arena!&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The TopCoder Competitions Team&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;$32 賞金がもらえることになりました．
「どうやって，賞金をうけとればよいのか？？？」
と思って調べていたのですけど，やはり手続きが面倒そうです．．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;宣誓証書&lt;/li&gt;
&lt;li&gt;Tax Form&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;などを一度は郵送でTopCoderへ送っておく必要があります．
賞金を受け取らずにチャリティーに寄付することもできるそうなので，寄付しようかな．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;問題空間のコンパクト化&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113561518668166547?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113561518668166547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113561518668166547'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/12/srm277.html' title='SRM277 - 初賞金げっと'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113478402333664719</id><published>2005-12-17T00:30:00.000+09:00</published><updated>2006-10-29T01:11:53.223+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>マラソン・マッチ</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;TopCoder が新しい形式のアルゴリズム・コンテストを開始しました．
&lt;a class="reference" href="http://www.topcoder.com/longcontest/?module=Static&amp;amp;d1=instructions"&gt;マラソン・マッチ&lt;/a&gt; です．
現在，ベータ・テストを行っています.&lt;/p&gt;
&lt;img alt="Marathon Match" src="http://static.flickr.com/56/193899298_477be1d4d2_o.jpg"/&gt;
&lt;p&gt;通常の短期決戦のSRMと違い長期戦です．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;期間は1週間&lt;/li&gt;
&lt;li&gt;与えられる問題は，いわゆる「正解」があるような問題ではない．&lt;/li&gt;
&lt;li&gt;期間内なら何回でもSubmitできる&lt;/li&gt;
&lt;li&gt;SubmitしたCodeは，ある基準（問題による）に従い採点されスコアがつけられる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;なるほど面白そうです.
どんな問題が出題されているのか，興味があったので参加してみました．
まだコンテスト期間内なので，問題の内容について書くことはできないですが，うーんなるほど．って感じです．
既に参加者は700名を超えているようです．&lt;/p&gt;
&lt;img alt="http://static.flickr.com/43/74278329_af0e3d5d2f_o.png" src="http://static.flickr.com/43/74278329_af0e3d5d2f_o.png"/&gt;
&lt;p&gt;早速，誰もが思いつくような方法でCodeを書いてみてSubmitしてみました．現在，43位です．&lt;/p&gt;
&lt;img alt="http://static.flickr.com/40/74278387_b424170e97_o.png" src="http://static.flickr.com/40/74278387_b424170e97_o.png"/&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113478402333664719?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113478402333664719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113478402333664719'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/12/blog-post.html' title='マラソン・マッチ'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113480537881336127</id><published>2005-12-16T00:30:00.000+09:00</published><updated>2006-10-31T03:06:58.627+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>reStructuredTextでblogger</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;このBlogは， もともとは &lt;a class="reference" href="http://docutils.sourceforge.net/rst.html"&gt;reStructuredText&lt;/a&gt; 形式で書いています．
ここで公開しているのはそれをHTMLに変換した結果です．
Blogger では， &lt;a class="reference" href="http://code.blogger.com/archives/atom-docs.html"&gt;ATOM API&lt;/a&gt; が用意されているので，
ありがたいことにブラウザを使用しなくてもBlogの更新ができます．&lt;/p&gt;
&lt;p&gt;以下のような手順をとっています．&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;reStructuredText形式で，テキストファイルを作成&lt;/li&gt;
&lt;li&gt;Python，docutils で html に変換&lt;/li&gt;
&lt;li&gt;2のhtmlを ATOM API で Blogger.comへ更新&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2と3はひとつのPythonスクリプト内で行っています．
reStructuredText から html への変換は，docutilsで行えます．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
from docutils.core import publish_parts
parts = publish_parts(
    content,
    writer_name='blogwriter'
    )
&lt;/pre&gt;
&lt;p&gt;docutils付属の html_writer を継承して・ほんの少しだけ修正した 自作のblogwriter を使用しています．
変換された，htmlのタイトル( &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;parts['title']&lt;/span&gt;&lt;/tt&gt; )と，body部分 &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;parts['body']&lt;/span&gt;&lt;/tt&gt; を，以下のテンプレートにセットして&lt;/p&gt;
&lt;pre class="literal-block"&gt;
entrytemplate = u'''&amp;lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&amp;gt;
&amp;lt;entry xmlns="http://purl.org/atom/ns#"&amp;gt;
 &amp;lt;title mode="escaped" type="text/plain"&amp;gt;%(title)s&amp;lt;/title&amp;gt;
 &amp;lt;issued&amp;gt;%(issued)s&amp;lt;/issued&amp;gt;
 &amp;lt;generator url="http://www.yoursitesurlhere.com"&amp;gt;python&amp;lt;/generator&amp;gt;
 &amp;lt;content type="application/xhtml+xml"&amp;gt;
   &amp;lt;div xmlns="http://www.w3.org/1999/xhtml"&amp;gt;
   %(content)s
   &amp;lt;/div&amp;gt;
 &amp;lt;/content&amp;gt;
%(draft)s
&amp;lt;/entry&amp;gt;'''
&lt;/pre&gt;
&lt;p&gt;ATOM API で送れば，Blogの更新が行えます．
これらの一連の作業を行う &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;myblogger.py&lt;/span&gt;&lt;/tt&gt; というPythonスクリプト を作成して使用しています．
テキストファイルを入力として，コマンド一発でBlogエントリの新規作成・更新を行えます．
以下のような感じです&lt;/p&gt;
&lt;pre class="literal-block"&gt;
myblogger.py merge 273.txt
&lt;/pre&gt;
&lt;p&gt;書きなれた reStructuredText 形式で Blogを書けるのは快適です．
ATOM API はほとんどのBlogサービスがサポートしているはずですので，
もし将来Blogを引越しすることになっても，ローカルにあるテキストを全部再発行するだけですみます．&lt;/p&gt;
&lt;p&gt;TopCoder のコンテストでは，現在，使用できる言語はJava, C#, C++, VB の4つだけです．
Pythonが使えるようにならないかなー．&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113480537881336127?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113480537881336127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113480537881336127'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/12/restructuredtextblogger.html' title='reStructuredTextでblogger'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113478103042860424</id><published>2005-12-13T02:28:00.000+09:00</published><updated>2006-10-29T01:11:53.157+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>2006 TopCoder Open - NSAがスポンサーに</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/tc?module=Static&amp;amp;d1=tournaments&amp;amp;d2=tco06&amp;amp;d3=about"&gt;2006 TopCoder Open&lt;/a&gt; が開催されるようです．&lt;/p&gt;
&lt;p&gt;賞金総額は，$150,000 です．
予選，Round1,2,3,4，そしてオンサイト（ラスベガス）でのファイナル というふうに，
何回かにわけて行われる形式のようです.
あの &lt;a class="reference" href="http://www.topcoder.com/tc?module=Static&amp;amp;d1=tournaments&amp;amp;d2=tco06&amp;amp;d3=nsa"&gt;NSA (National Security Agency)&lt;/a&gt; がスポンサーになるようですね．
いい成績を残せた人は，NSAから声がかかるのでしょうか？&lt;/p&gt;
&lt;p&gt;予選は，来年2月28日です．とりあえず，予選通過(750名)を目標に挑戦してみたいと思います.&lt;/p&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113478103042860424?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113478103042860424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113478103042860424'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/12/2006-topcoder-open-nsa.html' title='2006 TopCoder Open - NSAがスポンサーに'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113477976267174273</id><published>2005-12-09T02:28:00.000+09:00</published><updated>2006-10-29T01:11:53.080+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM276 - お買い物は楽しくDPで</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8073"&gt;SRM276&lt;/a&gt; に挑戦．
かなーり，眠かったので，スルーしようかと思ったのですが，挑戦しました．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5945&amp;amp;rd=8073"&gt;VolumeDiscount&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246939&amp;amp;rd=8073&amp;amp;pm=5945&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
お買い物です．たとえば，&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;1個なら4$&lt;/li&gt;
&lt;li&gt;3個まとめて買うと10$&lt;/li&gt;
&lt;li&gt;20個まとめて買うと48$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;だったとします．50個，買いたいとします．最低何$ですむか？という問題です.
この例だと&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;20個 x 2 + 3個 x 3 + 1個 x 1= 50個 (48$ x 2 + 10$ x 3 + 4$ x 1 = 130$)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;がベストな買い方で，答えは 130 です．
しかし，50個ではなく，55個買いたいとすると，ベストな買い方は&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;20個 x 2 + 3個 x 5 = 55個 (48$ x 2 + 10$ x 5 = 146$)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ではなく&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;20個 x 3 = 60個 ( 48$ x 3 = 144$)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;です．答えは，144 になります．
SRM中は，入力条件が緩いのでBrute-Forceで十分いけると思ってSubmitしました．
チャレンジタイムでは，MemoizationなしのBrute-Forceではタイムアウトすると思われたのか,
2回チャレンジをうけました．チャレンジで使用された入力は&lt;/p&gt;
&lt;img alt="http://static.flickr.com/39/74265649_2eb414d63b_o.png" src="http://static.flickr.com/39/74265649_2eb414d63b_o.png"/&gt;
&lt;p&gt;と明らかに2秒タイムオーバー狙いです．
チャレンジタイム後に，チャレンジしてきた人に質問されました．
2秒以内に終わったのが，信じられなかったようです.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference" href="http://static.flickr.com/36/74263840_738db61dae_o.png"&gt;&lt;img alt="SRM276_CHAT" src="http://static.flickr.com/36/74263840_738db61dae_m.jpg"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;その後, HiltonLange さんには，さらに&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;{"51 1","1 99"}, 99 だと，失敗するんじゃない？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と指摘されました．
そのとおりです．この入力だと51個x2=101個，2ドルが正解ですが，SubmitしたCodeでは&lt;/p&gt;
&lt;pre class="literal-block"&gt;
for (int i = 0; q + i * unit[n] &amp;lt; 100; i++) {
&lt;/pre&gt;
&lt;p&gt;このように上限を100にしていたため，51 x 1 + 99 * 48 = 4803ドルを出力していまいます．
上限は，最低200じゃないと．System Testに落ちますね．．．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
for (int i = 0; q + i * unit[n] &amp;lt; 200; i++) {
&lt;/pre&gt;
&lt;p&gt;このように上限200にしておくと，2秒近くかかりますが，なんとかSystem Testに通っていました．
それでも無駄だらけなので，無駄をなくすと共に，Memoizationを併用すれば，劇的に早くなります．
以下のようになります．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
int go(int q, int n) {
   if (n == N) {
       if (q &amp;lt; quantity) return 1000000;
       return 0;
   }
   if (cache[q][n] != 0) return cache[q][n];
   int min = Integer.MAX_VALUE;
   for (int i = 0;; i++) {
       min = Math.min(min, cost[n] * i + go(q + unit[n] * i, n+1));
       if (q + i * unit[n] &amp;gt;= quantity) break;
   }
   return cache[q][n] = min;
}
&lt;/pre&gt;
&lt;p&gt;この手の問題は，やはりDP(Dynamic Programming)を使うのが常套手段でしたね．
SRM後に書いてみました.&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public int bestDeal(String[] priceList, int quantity) {
    int N = priceList.length;
    int[] unit = new int[N];
    int[] cost = new int[N];
    for (int i = 0; i &amp;lt; N; i++) {
        unit[i] = Integer.parseInt(priceList[i].split(" ")[0]);
        cost[i] = Integer.parseInt(priceList[i].split(" ")[1]);
    }

    int[] best = new int[300];
    Arrays.fill(best, Integer.MAX_VALUE);
    best[0] = 0;
    for (int i = 0; i &amp;lt; N; i++) {
        for (int j = 0; j &amp;lt; quantity; j++) {
            if (best[j] != Integer.MAX_VALUE) {
                if (best[j] + cost[i] &amp;lt; best[j + unit[i]]) {
                    best[j+unit[i]] = best[j] + cost[i];
                }
            }
        }
    }

    int min = Integer.MAX_VALUE;
    for (int i = quantity; i &amp;lt; quantity + 100; i++) {
        min = Math.min(min, best[i]);
    }
    return min;
}
&lt;/pre&gt;
&lt;p&gt;ほとんどの人は，さくっと躊躇することなくDPを使用していました．さすが，Division1．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4634&amp;amp;rd=8073"&gt;TestingCar&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;500点問題．
レーシングカーの試験走行をします．
ただし，時間帯により制限速度の条件がいくつか与えられます.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;[5秒から10秒の間は，10 m/s以上スピードを出してはいけない ]&lt;/li&gt;
&lt;li&gt;[15秒から20秒の間は，15 m/s以上スピードを出してはいけない ]&lt;/li&gt;
&lt;li&gt;[30秒から40秒の間は，5 m/s以上スピードを出してはいけない ]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というふうにです．
入力として&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;レーシングカーの加速度 a (m / s^2 )  (減速度(?) も兼ねています．）&lt;/li&gt;
&lt;li&gt;試験走行の時間 (duratation) が与えられます.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この条件のもとで，レーシングカーが出せる最高速度はいくつになるかという問題です.
SRM中は，途中で方針が間違っていたことことにきずき，お手上げでした．
（つぎのつぎの制限速度の変更を考慮していなかったため減速が間に合わない．）&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5934&amp;amp;rd=8073"&gt;ForceTest&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
Openしませんでした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8073&amp;amp;rm=246939"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/9/74683887_7179f797b8_o.png"/&gt;
&lt;p&gt;レーティングは低下．今日は，敗北感が強いな．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;DPをちゃんとマスターしておく&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113477976267174273?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113477976267174273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113477976267174273'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/12/srm276-dp.html' title='SRM276 - お買い物は楽しくDPで'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113448905807715231</id><published>2005-11-22T00:30:00.000+09:00</published><updated>2006-10-29T01:11:53.007+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM273 - bit演算はintで行われるのね</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8070"&gt;SRM273&lt;/a&gt; に挑戦．
はじめて，平日の昼に挑戦です．今までは，日本時間の夜に開催されるSRMにしか参加しませんでした．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5895&amp;amp;rd=8070"&gt;FallingCoconuts&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246824&amp;amp;rd=8070&amp;amp;pm=5895&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
ココナッツを上から落としておとしていきます．積みあがった形を返す問題です．テトリスみたいなものですね．
番人(Sentinel)というちょっとしてTipsを使いました．
あらかじめ，一番下の段にココナツを敷き詰めておけば，ココナツが下にはみだすことはありません．
一番下までココナツが落ちたときの条件をチェックする必要がなくなります．
一番下の段に敷き詰めたココナツば番人がわりになってくれるわけです．
今回は，特にSentinel を使うまでもないですが，ときどきあらかじめSentinelを用意しておけば，
条件チェックが非常に楽になるケースがあります．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5893&amp;amp;rd=8070"&gt;SnakeTurbo&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246824&amp;amp;rd=8070&amp;amp;pm=5893&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
o---o-o-S--o--o--------G---o
&lt;/pre&gt;
&lt;p&gt;Sが Snake(へび)がいるスタート地点，Gがゴール地点です．へびは1秒に1単位進むことができます．
o はパワーアップえさです． o を食べるたびに，へび はスピードが2倍になります．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;2つ食べれば4倍&lt;/li&gt;
&lt;li&gt;3つ食べれば8倍&lt;/li&gt;
&lt;li&gt;4つ食べれば16倍&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というふうに，効果は累積します．
へびがスタート地点からゴールするまでの最短時間を求める問題です．&lt;/p&gt;
&lt;p&gt;これも，前回のSRM272のLevel2問題，RoundTableと同様に，Recursive + Memoization で解きました.
自信があったんですけど，System Testに落ちました．
うーん，どこがおかしいかしばらく気づきませんでした．．発見してみてください．
ここです&lt;/p&gt;
&lt;pre class="literal-block"&gt;
double boost = 1 &amp;lt;&amp;lt; (right - left);
&lt;/pre&gt;
&lt;p&gt;ここは，現在のへびのスピード，すなわち 2の (right - left) 乗 を求めているところです．
入力の条件は，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;orbs will contain between 0 and 50 elements, inclusive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;なので，(right - left) は32以上になる可能性があります．
右辺のビットシフトは int で計算が行われます．
int は32ビットなので，(right - left) が32以上のときは対応できません．
素直に&lt;/p&gt;
&lt;pre class="literal-block"&gt;
double boost = Math.pow(2, (right - left) );
&lt;/pre&gt;
&lt;p&gt;または&lt;/p&gt;
&lt;pre class="literal-block"&gt;
double boost = 1L &amp;lt;&amp;lt; (right - left);
&lt;/pre&gt;
&lt;p&gt;とlongを使用しておけば，何の問題もなく，System Testに通っていました．残念．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5878&amp;amp;rd=8070"&gt;RobotCollision&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;900点問題．
時間たりず．Level3 問題にしては，簡単なほうだったみたいです．
条件を絞れば，Brute-force でいけます．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8070&amp;amp;rm=246824"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/39/74683489_f24f748f7c_o.png"/&gt;
&lt;p&gt;レーティングはちょっとだけ上昇しました．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113448905807715231?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113448905807715231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113448905807715231'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/11/srm273-bitint.html' title='SRM273 - bit演算はintで行われるのね'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113422252929796191</id><published>2005-11-20T00:30:00.000+09:00</published><updated>2006-10-29T01:11:52.938+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM272 - Division1 - 4度目の正直</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8069"&gt;SRM272&lt;/a&gt; に挑戦．
今回のSRMは，msnがスポンサーです．$5,000の賞金がでます．
TopCoderでは，ときどきこのようなSponsored Match が行わています．
優秀な人材がほしい企業と，名を売りたい人たちの出会いの場の役目も果たしています.&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5886&amp;amp;rd=8069"&gt;FewestFactors&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246773&amp;amp;rd=8069&amp;amp;pm=5886&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
数字(0〜9)が最大5個与えられます．
それらを並べ替えてできる最大5桁の数のうち，Factor(約数)の数が最も少ないものを求める問題です．
たかだか最大5個ですので，全ての並び方を試せばOKです．いわゆるpermutationです．
C++ だと， STL にその名もずばり &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;next_permutation()&lt;/span&gt;&lt;/tt&gt; がありますので，それを使うとよいです．
C++以外の言語では，DFS (depth first search)で再帰的にpermutationを生成すればよいでしょう．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4835&amp;amp;rd=8069"&gt;RoundTable&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246773&amp;amp;rd=8069&amp;amp;pm=4835&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．
A社の代表 (countA)人 と B社の代表 (countB) 人が円卓に座ってミーティングをします．
椅子の数 は (chairs) です．
同じ会社の人どおしは，隣り合って座ってもよいですが，
A社の人とB社の人は，間に距離をいす(minDistance) 分だけあけて座らなければいけません．&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;minDistance = 1 は，隣り合っていてもいいです．&lt;/li&gt;
&lt;li&gt;minDistance = 2 だと，間に最低1つのいすが必要．&lt;/li&gt;
&lt;li&gt;minDistance = 3 だと，間に最低2つのいすが必要．&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;というわけです．可能な座り方の数はいくつか? という問題です．
SRMでは，Recursive と Memoization というパターンでときました．
この手の問題は，DP(Dynamic Programming:動的計画法)を用いることもできます．
こんな感じになります．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public class RoundTable {

  public long arrangements(int countA, int countB, int chairs, int minDis) {
    long[][][][][] dp = new long[chairs][minDis][minDis][countA+1][countB+1];
    dp[0][0][minDis-1][countA-1][countB] = 1;
    for (int c = 1; c &amp;lt; chairs; c++) {
        for (int pa = 0; pa &amp;lt; minDis; pa++) {
            for (int pb = 0; pb &amp;lt; minDis; pb++) {
                for (int a = 0; a &amp;lt;= countA; a++) {
                    for (int b = 0; b &amp;lt;= countB; b++) {
                        int npa = Math.min(minDis-1, pa+1);
                        int npb = Math.min(minDis-1, pb+1);
                        // Neither sit on the chair
                        dp[c][npa][npb][a][b] += dp[c-1][pa][pb][a][b];

                        // Arep can sit on the chair
                        if (pb == minDis-1 &amp;amp;&amp;amp; a &amp;gt; 0)
                            dp[c][0][minDis-1][a-1][b] += dp[c-1][pa][pb][a][b] * a;

                        // Brep can sit on the chair
                        if (pa == minDis-1 &amp;amp;&amp;amp; b &amp;gt; 0 &amp;amp;&amp;amp; c + minDis &amp;lt;= chairs )
                            dp[c][minDis-1][0][a][b-1] += dp[c-1][pa][pb][a][b] * b;
                    }
                }
            }
        }
    }

    long ret = 0;
    for (int pa = 0; pa &amp;lt; minDis; pa++) {
        for (int pb = 0; pb &amp;lt; minDis; pb++) {
            ret += dp[chairs-1][pa][pb][0][0];
        }
    }
    return ret * chairs;
  }
}
&lt;/pre&gt;
&lt;p&gt;レーティングが高い人たちは，平気でDPを使用してきます.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5883&amp;amp;rd=8069"&gt;ManhattanDistance&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
これも，DPでいける と思ったのですけど，500点問題で時間をほとんど使いきったため，さすがに時間が足りませんでした.
グラフをつくって，Dijkstra法でもいけます．1000点問題にしては，とっかかりやすいかと．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8069&amp;amp;rm=246773"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/37/74683080_2722d5598e_o.png"/&gt;
&lt;p&gt;ようやく，Division1ではじめてSystem Testに通りました．
Level2問題も解けたので，充実感．
レーティングは 1214 -&amp;gt; 1429 と上昇しました．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113422252929796191?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113422252929796191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113422252929796191'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/11/srm272-division1-4.html' title='SRM272 - Division1 - 4度目の正直'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113405411346856373</id><published>2005-11-04T00:30:00.001+09:00</published><updated>2006-10-29T01:11:52.864+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM270 - Integer == Integer</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8067"&gt;SRM270&lt;/a&gt; に挑戦．Division1に挑戦するのはこれが3回目ですが，前の2回は，&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Level1問題 - どちらもSubmitするも，単純なミスでSystem Testに落ちる.&lt;/li&gt;
&lt;li&gt;Level2問題 - どちらも時間切れ．&lt;/li&gt;
&lt;li&gt;Level3問題 - Openしたことさえありません．．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;とまだ1問もSystem Testに通ったことがありません．今度こそは1問は通るように．．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4658&amp;amp;rd=8067"&gt;CountriesRanklist&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246708&amp;amp;rd=8067&amp;amp;pm=4658&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;300点問題．
Codeは提出．今度こそ大丈夫と思っていたもの，またSystem Testで落ちてしまいました．
どこがおかしいんだろとCodeを見ていて，5分ほど．ようやく間違いを発見しました．ここです&lt;/p&gt;
&lt;pre class="literal-block"&gt;
if (l.get(i) == maxscore.get(key))
&lt;/pre&gt;
&lt;p&gt;Integer と Integer を == で比較しています．．．あーやってしまった．
J2SE5からautoboxing/unboxing が使えるようになりましたが，すっかりそれに頼りきっていました．
このように左辺 と 右辺 ともに Integer の場合は，だめですね．．equals(..) じゃないと．
どちらかがintならよかったんだけど．また単純ミスだ．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4755&amp;amp;rd=8067"&gt;SalesmanDilemma&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;600点問題．
巡回セールスマン問題．．ではありません．
基本的には最短経路を求める問題に落ち着くのですが，
やっかいな点としてネガティブ・ループの考慮をする必要があります．
SRM中は，時間切れでSubmitできませんでした．もう少しだったんですけど．&lt;/p&gt;
&lt;p&gt;SRM後に，完成させたコードです．
タイムオーバーになるかと思ったのですが，今回の条件ではこれでも十分2秒以内でした．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
import java.util.Scanner;
public class SalesmansDilemma {

int[][] p;
int[] visited;
int destination;

final int NA = Integer.MIN_VALUE;
final int ENDLESS = Integer.MAX_VALUE;
final int IMPOSSIBLE = Integer.MIN_VALUE;

int goal = IMPOSSIBLE;

public String bestRoute(int towns, int origin, int destination,
        String[] travelCosts, int[] profits) {
    this.destination = destination;
    p = new int[towns][towns];
    for (int i = 0; i &amp;lt; towns; i++) Arrays.fill(p[i], NA);
    for (int i = 0; i &amp;lt; travelCosts.length; i++) {
        Scanner s = new Scanner(travelCosts[i]);
        int from = s.nextInt();
        int to = s.nextInt();
        int cost = s.nextInt();
        p[from][to] = Math.max(p[from][to], profits[to] - cost);
    }

    visited = new int[towns];
    Arrays.fill(visited, IMPOSSIBLE);
    visited[origin] = 0;
    go(origin);

    if (goal == IMPOSSIBLE) return "IMPOSSIBLE";
    if (goal == ENDLESS) return "ENDLESS PROFIT";
    return "BEST PROFIT: " + (goal + profits[origin]);
}

void go(int town) {
    if (town == destination) goal = Math.max(goal, visited[town]);

    for (int i = 0; i &amp;lt; p[town].length; i++) {
        if (p[town][i] == NA) continue;

        int old = visited[i];
        int update = (visited[town] == ENDLESS) ?
                     ENDLESS : visited[town] + p[town][i];

        if (old == IMPOSSIBLE) {
            visited[i] = update;
            go(i);
            visited[i] = old;
        } else if (update &amp;gt; old) {
            visited[i] = ENDLESS;
            go(i);
            visited[i] = old;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;この手の問題では，Bellman-Ford アルゴリズムを用いるのが定石のようです．
ある地点からある地点までの，最短経路，およびネガティブ・ループを発見するアルゴリズムです．
練習がてら，Javaで実装してみました．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
import java.util.Scanner;
public class SalesmansDilemma {

class Edge {
    int source;
    int destination;
    int weight;
}

public String bestRoute(int towns, int origin, int destination,
        String[] travelCosts, int[] profits) {
    Edge[] edges  = new Edge[travelCosts.length];
    for (int i = 0; i &amp;lt; travelCosts.length; i++) {
        Scanner scan  = new Scanner(travelCosts[i]);
        edges[i] = new Edge();
        edges[i].source = scan.nextInt();
        edges[i].destination = scan.nextInt();
        edges[i].weight = scan.nextInt()
                         - profits[edges[i].destination];
    }
    long[] verticles = new long[towns];
    long INFINITY = Long.MAX_VALUE;
    for (int i = 0; i &amp;lt; verticles.length; i++) {
        verticles[i] = INFINITY;
    }
    verticles[origin] = 0;

    boolean[] negative = new boolean[towns];

    // relax and find negative cycle
    for (int i = 0; i &amp;lt; verticles.length + 1; i++) {
        for (Edge e : edges) {
            int u = e.source;
            int v = e.destination;
            if (verticles[u] == INFINITY) continue;
            if (verticles[v] &amp;gt; verticles[u] + e.weight) {
                verticles[v] = verticles[u] + e.weight;
                if (i == verticles.length) {
                    negative[v] = true;
                }
            }
        }
    }

    if (verticles[destination] == INFINITY) return "IMPOSSIBLE";

    boolean[] mark = new boolean[towns];
    for (int i = 0; i &amp;lt; towns; i++) {
        if (negative[i] &amp;amp;&amp;amp; !mark[i]) {
            go(i, mark, edges);
        }
    }
    if (mark[destination]) return "ENDLESS PROFIT";

    return "BEST PROFIT: " +
           -(verticles[destination] - profits[origin]);
}

void go(int v, boolean[] mark, Edge[] edges) {
    mark[v] = true;
    for (Edge e : edges) {
        if (v == e.source &amp;amp;&amp;amp; !mark[e.destination]) {
            go(e.destination, mark, edges);
        }
    }
}
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4751&amp;amp;rd=8067"&gt;PackingShapes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;900点問題．
SRM中はOpenしませんでした．
ある長方形のなかに，別の長方形をはみださないようにいれることができるか判定する問題です．
たとえば，幅100 x 高さ100 の長方形には，幅140 x 高さ1 の長方形は（傾ければ）いれることができます．
幅140 x 50 の長方形はどんなにがんばってもはいりません．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8067&amp;amp;rm=246708"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/37/74682670_24668897a1_o.png"/&gt;
&lt;p&gt;レーティングは 1303 -&amp;gt; 1214 と低下．かろうじてDivision1には残っています.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Primitive と ラッパー．．Javaを使い続ける限りつきまとう，もっとも頭のいたい問題です．
autoboxing/unboxing には惑わされないように．&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113405411346856373?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113405411346856373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113405411346856373'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/11/srm270-integer-integer.html' title='SRM270 - Integer == Integer'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113367212677932890</id><published>2005-10-19T00:30:00.000+09:00</published><updated>2006-10-29T01:11:52.734+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM268 - Division2脱出</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8001"&gt;SRM268&lt;/a&gt; に挑戦．Division2の問題です．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=5867&amp;amp;rd=8001"&gt;CrossWordPuzzle&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246654&amp;amp;rd=8001&amp;amp;pm=5867&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
1文字・1文字，順にチェックしている人が多かったようですが，
正規表現を使用した文字列分割 (いわゆる split(..)) が利用できる言語なら，それを使えば簡単です．
今回は正規表現を使用するほどでもないですが，正規表現を使用すれば，ずっと簡単になる問題もTopCoderではときどき出題されるようです．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=3490&amp;amp;rd=8001"&gt;CmpdWords&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=246654&amp;amp;rd=8001&amp;amp;pm=3490&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．
一見，問題がわかりにくいですが，ハッシュテーブルを使用して，合成文字列の重複のカウントをすれば，これも簡単です．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4699&amp;amp;rd=8001"&gt;TriArea&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
重なり合う2等辺三角形が複数与えられます．それらがカバーする面積をもとめる問題です.
3角形の重なりを判定して全体の面積を求めようととしたのですが，
1時間以上，格闘したあげく，時間切れでした．&lt;/p&gt;
&lt;p&gt;パラメータの条件として&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Each element of xCenter and yCenter will be between -100 and 100, inclusive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあるので，全2次元空間をひたすら調べたほうが簡単でした.
1 x 1 のグリッドをさらに4つのエリアにわけて，そのエリアが三角形に含まれているなら&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(面積) += 0.25&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とすればよいです．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
public class TriArea {

  public double area(int[] xCenter,
                     int[] yCenter, int[] height) {
    double res = 0;
    int N = xCenter.length;
    int[] dx = {1, 2, 2, 3};
    int[] dy = {2, 1, 3, 2};
    for (int x = -200; x &amp;lt; 200; x++) {
      for (int y = -100; y &amp;lt; 200; y++) {
        for (int d = 0; d &amp;lt; 4; d++) {
          double nx = x + dx[d] / 4.0;
          double ny = y + dy[d] / 4.0;
          for (int i = 0; i &amp;lt; N; i++) {
            if (ny &amp;lt; yCenter[i]) continue;
            if ( height[i] &amp;gt; Math.abs(xCenter[i] - nx)
                  + (ny - yCenter[i])) {
              res += 0.25;
              break;
            }
          }
        }
      }
    }
    return res;
  }
}
&lt;/pre&gt;
&lt;p&gt;これでも，Order は 400 x 400 x 4 x 25(3角形の最大数) ですから，これで十分いけましたね．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8001&amp;amp;rm=246654"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/43/74682258_bc8a562129_o.png"/&gt;
&lt;p&gt;1000点問題ができなかったのが悔やまれますが,250点問題と500点問題は早めにSubmitできたためか，
ルーム内ではTopのポイントでした．
レーティングは 1152 -&amp;gt; 1303 と 1200を超えたので，Division2脱出です．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;入力条件をよくチェックする．入力条件によっては，エレガントに解く必要はない．
全部調べても大丈夫な場合がある．特にDivision2は．&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113367212677932890?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113367212677932890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113367212677932890'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/10/srm268-division2.html' title='SRM268 - Division2脱出'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113361523481666453</id><published>2005-10-02T00:30:00.000+09:00</published><updated>2006-10-29T01:11:52.655+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM266 - NASA, we have a problem...</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=7999"&gt;SRM266&lt;/a&gt; に挑戦．
Division2落ちしたので，今日からはDivision2．
一発でDivision1に復帰するのが目標．
前回，TopCoderに初挑戦したときは，Division2の問題は3問ともSubmitできたので（1問は間違っていたけど．．），今回もなんとかなるか，と甘い気持ちでスタート．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4821&amp;amp;rd=7999"&gt;SwimmersDelight&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=203780&amp;amp;rd=7999&amp;amp;pm=4821&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
幅が10フィートの川があります．間には足場となる2つの石があります．
最適な飛び方をした場合,もっとも長いジャンプはどれだけの長さですむか？という問題です．
石の座標(x, y) (xが川の幅方向: 0&amp;lt;=x&amp;lt;=10) が(3, 5), (6, 2)だとすると，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;スタート (0, 5) --(距離3)--&amp;gt; (3, 5) --(距離4.24..)--&amp;gt; (6, 2) --(距離4)--&amp;gt; (10, 2) 到着&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;といけば，最大のジャンプは 4.24.. ですみます.
全部のパスを調べればよいだけの問題ですので，さくっと終わらせて（といっても13分かかってますけど）．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4809&amp;amp;rd=7999"&gt;ExploringEuropa&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;550点問題．
木星の月・Europa上の地表探査機に対して，NASAから指示（「REVERSE」「STOP」）を出して，
ちょうど 探査対象 の上に探査機を停めたい．
いつ指示をだすのがBestか？という問題です.
NASAと探査機の間は，すぐに指示が伝わらなくDelayが生じる．のが問題の肝です．
問題文が長いのはいいとして，問題を呼んだ直後はそんなに難しいとは思わなかったのですけど，，
はまりました．．．
1時間以上格闘したあげく，結局時間切れでした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4808&amp;amp;rd=7999"&gt;ZCurve&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;900点問題．
SRM中はOpenしませんでしたが，こちらのほうが簡単でした．
ExploringEuropa はとっとと捨てて，こちらににとりかかればよかった．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=7999&amp;amp;rm=203780"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/41/74681944_23c573b1ab_o.png"/&gt;
&lt;p&gt;ExploringEuropa と ZCurve は Division1のLevel1(300点)問題, Level2(450点)問題にも使用されていました．
どちらのDivisionの結果をみても，ExploringEuropaの方が，あきらかに正解率が悪かったです．
なかなか状況把握やとっかかりがつかみにくいようで，みなさん苦労したようです．
難易度とポイントのバランスを考えると，「問題をいれかえるべきだったのでは?」という声が多かったです.
その気になれば，手作業・手計算でも正解を導き出せる問題なんですけどね．
レーティングはさすがに下がると思っていたけれど，ちょっとだけ上昇でした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;はまったときはその問題を捨てて次の問題へ．必ずしも順番に解いていく必要はなし．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Division2脱出はならず．．次回もDivision2です．．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113361523481666453?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113361523481666453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113361523481666453'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/10/srm266-nasa-we-have-problem_02.html' title='SRM266 - NASA, we have a problem...'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113361367828536009</id><published>2005-09-28T00:30:00.001+09:00</published><updated>2006-10-29T01:11:52.580+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM265 - Division2落ち...</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=8007"&gt;SRM265&lt;/a&gt; に挑戦．
前回急降下したレーティングは1255です．まだ1200以上なのでかろうじてDivision1には残っています．
前回はポイント ゼロだったので，今回こそは一問でいいからSystem Testに通ることを目標に．今回もゼロだとおそらく1200以下に落ちます．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=1993&amp;amp;rd=8007"&gt;ScheduleStrength&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=203701&amp;amp;rd=8007&amp;amp;pm=1993&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
リーグ戦において&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;ある2チームの勝率が同じだった&lt;/li&gt;
&lt;li&gt;どちらか1チームをプレーオフに進出させなければいけない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このような状況のとき，より厳しいスケジュール・強い対戦相手と戦ってきたチームを優先させましょう．
このスケジュールの厳しさを計算せよという問題です．
これもやはりただ実装するだけという問題なのですが，最初，意味を勘違いしていたこともあり，
大幅に時間がとられてしまいました．
しかし，44分は時間かけすぎ．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4708&amp;amp;rd=8007"&gt;Recipe&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;500点問題．
料理の正しいレシピ (例 - 塩:大さじ4，砂糖:小さじ18, 醤油: カップ2杯) と，
実際にボールに入れて混ぜてしまった量(例 - 塩:大さじ4，砂糖:小さじ19, 醤油: カップ3杯)が与えられます．
この時，正しいレシピの割合にするには，ボールにあとどれだけ各調味料をいれればよいでしょうか？という問題です．
必要以上にいれてはいけません．
この例の場合は，あと (塩:大さじ4，砂糖:小さじ17, 醤油: カップ1杯) 追加はいれすぎです．
正解は(塩:大さじ2，砂糖:小さじ8, 醤油: カップ0杯) になります．&lt;/p&gt;
&lt;p&gt;うーん，時間切れでした．
最大公約数を使用すれば，エレガントにとけますが，それ以外の方法では制限時間の2秒以内には終わらない可能性があります．
実際，SRM後にコードを完成させたのですが，最悪の入力ケースでは2秒以内に終了しませんでした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=1981&amp;amp;rd=8007"&gt;PokerDeck&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．SRM中はOpenできませんでした．
この問題に正解したのは，Division1参加者333人中1人だけです．． ( &lt;a class="reference" href="http://www.topcoder.com/tc?module=ProblemDetail&amp;amp;rd=8007&amp;amp;pm=1981"&gt;Problem Detail&lt;/a&gt; )&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;今度こそ，250点問題はPassすると思ったのけど..．System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=8007&amp;amp;rm=203701"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/6/74681550_405b300ecd_o.png"/&gt;
&lt;p&gt;あれー．またSystem Testに落ちてる．ここでした．．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
t.p = (double) w / (double) l;
&lt;/pre&gt;
&lt;p&gt;勝率の計算を win / (win + lose) でなく，win / lose で行っています．
またもや，あきれるくらいの単純なミス．これでExampleにすべて通ってしまったのが，運が悪かった．．
今回も，Challenge Timeでは誰もここにきずかなかったのか，誰もチャレンジしてきませんでした．&lt;/p&gt;
&lt;p&gt;他の人のソースを見てみると，あらかじめ，勝率を&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(double)w / (double) total
&lt;/pre&gt;
&lt;p&gt;と （勝数) / (試合数) を計算しておいて，doubleになった勝率どおしを比較するのではなく，&lt;/p&gt;
&lt;pre class="literal-block"&gt;
my.win * your.total - your.win * my.total
&lt;/pre&gt;
&lt;p&gt;として，比較しているのが見受けられます．
全て整数どおしの計算になるので，doubleにまつわる問題を避けることができます．なるほど．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Example Caseにとおったからといって，正解とはかぎらない．&lt;/li&gt;
&lt;li&gt;おちつけ&lt;/li&gt;
&lt;li&gt;doubleどおしの比較は避けれるものなら避ける．
整数ですべて片付くならそちらを採用.
(a / b) と (c / d) を比較するには a/b - c/d ではなく，a * d - c * b のほうがよい．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;レートは 1255 -&amp;gt; 1097 とやはり急降下．Division2行きが決定しました．．．名前も緑に．
2軍におちる選手の心境がすこしはわかったような．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113361367828536009?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113361367828536009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113361367828536009'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/09/srm265-division2_28.html' title='SRM265 - Division2落ち...'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113357754931995752</id><published>2005-09-10T00:30:00.000+09:00</published><updated>2006-10-29T01:11:52.360+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM262 - 初Division1はTypoに終わる</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=7996"&gt;SRM262&lt;/a&gt; に挑戦．
レートが1200以上の人はDivision1なので，今日からはDivision1．
75分で3問という点はDivision2と同じだが，問題の内容はDivision2と比べてかなーり難しい（はず）．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4557&amp;amp;rd=7996"&gt;SortBooks&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=203562&amp;amp;rd=7996&amp;amp;pm=4557&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．
本のタイトルの条件をみたすものをピックアップする問題．
アルゴリズム的には悩むところはなくただ実装するだけ．
コーディングそのものは10分ほどで終わりましたが，作成したものにExampleと同じ入力を与えても，
正解例と異なる値が出力され，なかなかSubmitできません．
Exampleというのは，入力の例とその入力に対する正しい出力例のことです．
各問題には数個のExampleがついてきます．
最低限，Exampleで動作確認してから，Submitすべきです．&lt;/p&gt;
&lt;p&gt;そのExample Caseに通りません．．．
おかしいとおもいつつ，あせりまくり，デバッグをはじめたが，なにがおかしいかさっぱり．
とりあえずこれ以上250点問題に時間をかけるわけにはいかないので30分過ぎたところでSubmitしました．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4797&amp;amp;rd=7996"&gt;BestYahtzeeScore&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;500点問題．
5個のダイスを3回まで振ることができた場合（2回目以降は，振らずに残しておいてもいいです），
5個の目の組み合わせで決まるスコアの最大値を返す問題．
ダイスをふると何がでるかは，あらかじめ長さが15の文字列で与えられます．
...時間切れでした．最終的に可能な5個の目の組み合わせをすべて試せばいいのですが，そこで手間取りました．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=932&amp;amp;rd=7996"&gt;MagicBoxes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;1000点問題．
コンテスト中はOpenできませんでした．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=7996&amp;amp;rm=203562"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/9/74681248_1f161f46ab_o.png"/&gt;
&lt;p&gt;やはり，250点問題はSystem Testに落ちました．結果，Scoreはゼロです．．．
あー，Typoでした．．ここです&lt;/p&gt;
&lt;pre class="literal-block"&gt;
if (w.equalsIgnoreCase("the") || w.equalsIgnoreCase("and")
        || w.equalsIgnoreCase("or")) {
    return 1;
&lt;/pre&gt;
&lt;p&gt;"of" とするべきところを，"or" としています．．本番中はまったく気づきませんでした．
ちなみにこの問題，はやい人は3分もかからずにSubmitしています ( &lt;a class="reference" href="http://www.topcoder.com/tc?module=ProblemDetail&amp;amp;rd=7996&amp;amp;pm=4557"&gt;Problem Details&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;こうしてみると，Division2ではJavaとC++使用者は同数ほどなのに，Division1 では C++使いが多いですね．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;文字列リテラルは 問題文からコピーandペーストすべき．&lt;/li&gt;
&lt;li&gt;Example Case はすべて通してからSubmit．やけになって途中でSubmitしても無意味です．
必ずどこかが間違っていますし，他の参加者にChallengeの機会を増やすことにもなります．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そういえば，今回はChallenge Time では，自分の250点問題には誰もChallengeしてきませんでした．
あまりに単純なミスすぎて逆に発見できなかったのか...
レートは 1579 -&amp;gt; 1255 と大幅に減りました．かろうじてDivision1には残っています．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113357754931995752?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113357754931995752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113357754931995752'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/09/srm262-division1typo_10.html' title='SRM262 - 初Division1はTypoに終わる'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-15880554.post-113357087496948810</id><published>2005-08-28T02:28:00.000+09:00</published><updated>2006-10-29T01:11:52.275+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='topcoder'/><title type='text'>SRM260 - TopCoderへの挑戦のはじまり</title><content type='html'>&lt;div xmlns="http://www.w3.org/1999/xhtml"&gt;
    &lt;p&gt;&lt;a class="reference" href="http://www.topcoder.com/"&gt;TopCoder&lt;/a&gt; とは，世界中のトッププログラマが集まり，プログラミングスキルを競いあっているサイトです．
毎週のようにオンラインでプログラミングコンテストが行われています．
面白そうなので参加してみました． &lt;a class="reference" href="http://www.topcoder.com/stat?c=round_overview&amp;amp;rd=7994"&gt;SRM260&lt;/a&gt; に挑戦です．SRMとはSingle Round Match のことです．定期的に（週に1回ほど）開催されています．&lt;/p&gt;
&lt;p&gt;先日開催されたGoogle Code Jam 2005でこのサイトを知った人が多いのかいつもより参加者が多いらしく（私もその一人），驚いている様子が伺えます(800名オーバー)．&lt;/p&gt;
&lt;img alt="Chat Area" src="http://static.flickr.com/26/38216141_06b79260a9_o.png"/&gt;
&lt;p&gt;レーティングが1200以上の人はDivision1，それ以下の人はDivision2になります．
Division1の方が問題が比較的易しくなっています．
初参加の自分は，Devision2．&lt;/p&gt;
&lt;p&gt;簡単にSRMの流れをおさらいしておくと&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;開始時間の5分前までにRegistrationを行う&lt;/li&gt;
&lt;li&gt;参加者は約20名づつ，Roomにアサインされる&lt;/li&gt;
&lt;li&gt;問題は3問．制限時間は75分．言語は Java, C++, C#, VB から選択できます．&lt;/li&gt;
&lt;li&gt;5分休憩&lt;/li&gt;
&lt;li&gt;15分のチャレンジタイム．この時間では，同じルームの参加者が提出したコードを見ることができます．
バグを発見し「チャレンジ」に成功すると50ポイントもらえます．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということです．この4つから選ぶなら(無難に?)Javaでいきます．以下のような問題が出題されました．(code) は私が提出したコードです．&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4746&amp;amp;rd=7994"&gt;IsingModel&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=203409&amp;amp;rd=7994&amp;amp;pm=4746&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;250点問題．特に難しいところはないです．軽くこなしたいところ．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4766&amp;amp;rd=7994"&gt;GridPointsOnCircle&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=203409&amp;amp;rd=7994&amp;amp;pm=4766&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;500点問題．中心(0,0)，半径rの円上に座標が(整数, 整数)の形式を満たす点はいくつ存在する？って問題です．
ちょっと，なやむ．
単に (x, y) ( 0 &amp;lt;= x, y &amp;lt;= r) を全部調べていたらタイムオーバするってのが目に見えてるので，なんらかのちょっとした工夫が必要．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_statement&amp;amp;pm=4749&amp;amp;rd=7994"&gt;RollingBlock&lt;/a&gt; (&lt;a class="reference" href="http://www.topcoder.com/stat?c=problem_solution&amp;amp;rm=203409&amp;amp;rd=7994&amp;amp;pm=4749&amp;amp;cr=15632820"&gt;code&lt;/a&gt;)&lt;/h2&gt;
&lt;p&gt;1000点問題.
サイズがrows x cols の盤上を 1 x 1 x 3 のブロックがごろんごろんと動くとき，ある地点からゴールの地点まで最短，何Moveで到達できるか？という問題です．
条件として，&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;rows and cols will be between 1 and 100, inclusive.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあるので，状態空間はたかだか 100 x 100 x 3 くらいです．
BFS (Breadth First Search) で問題ない（はず）．
不正な状態（盤からはみだす)をちゃんとチェックしてやれば，なんとかなるか．．&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;制限時間つきでコーディングするなんていう経験が普段ないもんだから，あせるあせる．
で，なんとか3問ともSubmitしました．
問題をOpenしてから，Submitするまでの時間が早ければ早いほどポイントが高くなります．&lt;/p&gt;
&lt;p&gt;&lt;a class="reference" href="http://static.flickr.com/30/38216143_7153b1a67d_o.png"&gt;&lt;img alt="SUBMIT_RESULT" src="http://static.flickr.com/30/38216143_7153b1a67d_m.jpg"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;75分のコーディングタイムが終了すると，5分の休憩があります．
その後，15分間のChallenge Timeが始まりました．&lt;/p&gt;
&lt;p&gt;自分の500点コードが撃墜された瞬間．．&lt;/p&gt;
&lt;p&gt;&lt;a class="reference" href="http://static.flickr.com/25/38216144_aa73121e35_o.png"&gt;&lt;img alt="CHALLENGE" src="http://static.flickr.com/25/38216144_aa73121e35_m.jpg"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Challengeで使用されたパラメータ(円の半径)は入力条件の最大値である2000000000です．
その結果は&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;"The code execution time exceeded the 2 second time limit."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2秒以上実行時間がかかるのは認められないってことですね．．なるほど．．
このように，あらかじめ，必要な上限のみに制限しておけば2秒以内だったか．．&lt;/p&gt;
&lt;pre class="literal-block"&gt;
long r = (long) Math.sqrt(rSquare) + 1;
long y = r;
for (long x = 0; x &amp;lt; r; x++) {
&lt;/pre&gt;
&lt;p&gt;自分もどきどきしながらひとつChallengeしてみました．結果は成功(+50点)．&lt;/p&gt;
&lt;p&gt;Challenge Timeが終わると，ひとまず終了です．
全員のSubmitされたコードに対してSystem Testが走ります．
System Testに落ちると，どんなに早くその問題をSubmitしていてもゼロ点です．&lt;/p&gt;
&lt;p&gt;System Testの結果です．
( &lt;a class="reference" href="http://www.topcoder.com/stat?c=coder_room_stats&amp;amp;cr=15632820&amp;amp;rd=7994&amp;amp;rm=203409"&gt;Room Statistics&lt;/a&gt; )&lt;/p&gt;
&lt;img alt="Room Statistics" src="http://static.flickr.com/40/74680799_df314e57a5_o.png"/&gt;
&lt;p&gt;250点問題と1000点問題は無事System Testに通りました．
1000点問題は2回チャレンジをうけています．そんなに「間違えてる」ふうに見えたのかなー．&lt;/p&gt;
&lt;p&gt;レーティングはこうなりました．&lt;/p&gt;
&lt;img alt="Rating" src="http://static.flickr.com/29/38216145_fde67a1953_o.png"/&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h2&gt;今日の教訓&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;2秒以内という時間制限を忘れないように&lt;/li&gt;
&lt;li&gt;いちばん時間がかかるケースをちゃんと考慮しておくように&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;なかなか普段は味わえない緊張感があって，面白かったです.
レーティングシステムというのがいいですね．また挑戦してみたいです．&lt;/p&gt;
&lt;/div&gt;
    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15880554-113357087496948810?l=4topcoder.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113357087496948810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15880554/posts/default/113357087496948810'/><link rel='alternate' type='text/html' href='http://4topcoder.blogspot.com/2005/08/srm260-topcoder_28.html' title='SRM260 - TopCoderへの挑戦のはじまり'/><author><name>gentoo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>
