日記2015年のICPC国内予選が開催されてから2ヶ月近く経ってしまいましたが、ようやく全問解き終わったので回答を公開しました。2008年が現役最後の年だったので実に7年ぶりの挑戦になりましたが、面白い問題も多く楽しむことができました(もちろん、苦しむことも!)。入出力データや順位表などの各種情報は出揃っていますので、興味がある方はそちらも見てみると面白いと思います。A〜Hの全部で8問でしたが、A〜Cが易しく、D〜FとHにやや苦戦、Gに大苦戦という感じでした。時間などは決めずに解いていましたが、本番の3時間半にあわせるとわたしは3〜4問くらいしか解けないだろうなと思います。個人的に面白かったのは問題EとFで、一番苦しんだのは問題Gでした。以降は、各問題についての概要、自分の解法とその説明です。回答ループが使えれば解ける問題で、どちらかというと落ち着いて問題文を読解できるかどうかが鍵だと思います。与えられるので、短句の条件を満たす最初の連続な部分列を求める問題です。短句の条件は次の通りです。回答カッコを使わない特殊な記法で記述された式の値を計算する問題です。構文解析しつつ式の評価を行うだけです。Archive)という記事を読んで、一度実装してみると同じような問題を解けるようになると思います。回答500円玉貯金をするために、買い物のお釣りで最大何枚の500円玉を得ることができるか、また、そのときに必要なお金の総額の最小値を求める問題です。一目見てDPだなと思いましたが、DPでした。表は、500円玉の最大枚数[n件目のお店][n件目で持っている小銭の総額]と構成しました。最終的な答えはこの表の最後の行の最大値になります。表の要素を計算するためには、次の3つのパターンを考慮するだけで十分です。お札だけ出して買う(500円玉の枚数は増えない。持っている小銭の総額が増える。お札と小銭を出して買う(500円玉の枚数は1枚だけ増える。持っている小銭の総額は減る。可能でない場合もある。)もう少し数学っぽく書くなら次のようになります(お釣りの計算方法は端折ります)。1)最終的な答えには500円玉の最大枚数だけでなく、そのときに必要なお金の総額の最小値も必要ですが、少し工夫するだけで対応できます。具体的には、500円玉の最大枚数の表と同じ大きさの表を用意して、500円玉の最大枚数の表が更新されたときだけ更新するだけでOKです。nは最大で100、xは最大で49900(1円の商品を売っているお店が100件ある場合)です。わたしは1度の買い物で得られる500円玉は高々1枚であることを見逃し、少しハマってしまいました。これは、例えば1000円のお釣りは、500円玉2枚ではなく1000円札1枚でお釣りが返ってくる、ということです。お釣りの枚数の最小化などの類題を解いた経験があれば、手持ちの金額を表のインデックスにするという点は同じなので、解法を思いつきやすいかなと思います。お釣りの枚数の最小化を知らない人は、DPの話に出てくるコインの両替問題を読んでみると良いと思います。与えられてデッドロックを検出する問題です。ロックとスレッド数は10個で固定ですが、命令長が最大10000です。状態数を考えると素直にシミュレーションするのはダメということは分かるので、DPっぽいなと思いましたがしばらく解けませんでした。2つのスレッドの場合を考えてみると、スレッドの状態(獲得済みのロック集合と、次に獲得しようとしているロック)が決まればデッドロックを判定できます。したがって、2つのスレッドの状態の組み合わせを列挙できれば良さそうです。1つのスレッドの状態を列挙するには、与えられた命令列を実行するだけです。1つのスレッドの状態が列挙できれば、2つのスレッドの状態の組み合わせも列挙できます。ここで、2つのスレッドの状態の組み合わせについてさらに考えてみると、次の4つのパターンに分類できることがわかります。任意の順序で実行できる」のケースは、どちらの状態も発生する可能性があります。デッドロックする」のケースは、お互いに獲得済みのロックを獲得しようとしているのでデッドロックします。このケースを一つでも検出したら、与えられた命令列が危険であると判断することができます。ブロックする」のケースは、両方のスレッドが獲得済みのロック集合の和集合を獲得済みで、ブロックされていない方のスレッドが獲得しようとしているロックを次に獲得しようとしている状態と考えることができます。同じロックを獲得済み」のケースは、発生することはないのでこの組み合わせの状態は無視します。(3)が重要で、これに気がつけば、1つのスレッドで発生する状態から、2つのスレッドで発生する状態、3つのスレッドで発生する状態、...と次々に求めていけることが分かります。したがって、10個のスレッドで発生する状態まで列挙して、その間にデッドロックする状態がなければ安全と判断することができます。10であることを考えると厳しいように思えますが、スレッドの状態数はそれほど多くならないようです。本建設するときの最小の費用を求める問題です。建設会社が1つであれば単なる最小全域木(MST)の問題ですが、2つだとどう構成すれば良いのか自明でなくなります。最初はDPで解けるのではないかと考えていましたが、うまく構成できる方法が思いつかず、最終的には証明なしで貪欲法で解きました。本になるまでMSTを保ったままA社の橋を使うと良くなる、あるいは、同じ橋を見つけて交換します。tmaeharaさんが国内予選F問題の解説のふりをしたマトロイドの解説で詳しく解説されていますので、そちらを参照するのが良いと思います。与えられた凸多角形を2つの頂点が重なるように1度だけ折ってできる多角形のうち最も複雑な多角形を求める問題です。複雑な多角形とは、頂点数が多く、同じ頂点数の場合には周長が長いことをいいます。問題Gが一番苦戦した問題でした。計算幾何の問題はコーナーケースが多いので間違えやすく、本番ではライブラリがないと解くことがなかなか難しいジャンルの問題だと思います。解法は、すべての頂点対に関して折ってみて、2つの凸多角形をマージしてできた多角形の中で最も複雑なものを計算すれば良いです。私がつまずいたのは、2つの凸多角形のマージ操作でした。外側の点列を追跡するだけなのですが、間違っている答えを出力したときにどこが間違っているのかを突き止めることが難しく、デバッグが難航しました。結局、計算途中と最終的な図形をPostScript形式で出力するようにして、間違いを視えるようにすることで、デバッグしきることができました。苦戦したサンプル入力の7個目の複雑な折り方を図にしてみました。外側の多角形が何度も入れ替わったり、1点だけ外側に出てすぐ内側に戻ったりするケースにハマっていました。サンプル入力7個目の折り方すべてをPDFにしておきましたので、興味のある方はみてみてください。1位の東大チームが本番中にこの問題を通していることに恐ろしさを感じました。ロボットの初期位置とマップが与えられるので、一箇所に集める最小コストを求める問題です。最上階までロボットを移動する操作と、最上階でロボットを一箇所に集める操作に分けて考えることができます。最上階までロボットを移動するために普通に幅優先探索するのではマップが広すぎるので時間切れになってしまいます。答えを計算するのに必要なセルだけでグラフを作って最上階までの最短路を計算すれば良さそうだな、と考えていました。最上階までに考慮すべきセルは次の図で赤と青のセルだけで十分です。最上階でどこのセルに集合させるのが一番良いかというと、次の図で赤と青のセルを考慮すれば良さそうに見えます。これだとダメなケースがあります。次の図では、真ん中に集合するのがエネルギー最小になります。審判長講評の集合場所の解説を読むと、次の場所を集合場所の候補として考えれば問題なさそうです。正確には、穴周辺のx座標とy座標と、最上階のロボットx座標とy座標をそれぞれ集めて、x座標とy座標の任意の組み合わせのセルが候補点になります。いうことで、審判長講評を見てしまいましたが、なんとか解くことができました。本番中に九州大学のチームだけがこの問題Hを通していて、素晴らしいと思いました。2015の国内予選の問題を解いて解説をまとめてみました。計算幾何の問題は解きたくなくなりましたが、たまにはプログラミングコンテストの問題を解いてみると、脳トレになっていいかもしれません。2015(言語処理学会第21回年次大会)に参加しました。京都大学で3月16日〜21日まで開催されていましたが、私は16日〜19日だけ参加しました。大まかな日程は次の通りです。...記事を読むおいしいコーヒーを楽しむ豆部についてこんにちは、レトリバでエンジニアをしている岩田です。11月に転籍してバタバタしているのですが、今回は会社の有志でやっている豆部の活動を紹介したいと思います。Cardboardとレーザーカッターを作った話をしました12月15日に久しぶりにPFxセミナーの担当が回ってきたので、趣味の(電子)工作の話をしました。話す内容は迷ったのですが、技術が絡んでいること、濃い内容を話せること、の2つで決めました。Jubatusにまつわる何かを作る会に参加してきました。参加者にはもれなくJubatusのぬいぐるみが配られました。今回はスタッフではなく、普通の参加者として参加しました。会場提供はIIJさんでした。電源、ネットワー...記事を読む2015年の振り返りと2016年の抱負2015年をざっくり振り返ると、元旦に「普通のことを普通にできるように」と抱負を決めて、なんとか達成はできたかなという感じです。これだと簡潔すぎるので、もう少しだけ細かく振り返ってみます。大きな盛り上がりをみせたスプラトゥーン甲子園も終わり、このまま緩やかに下火になっていくと思っていたスプラトゥーンですが、夏までアップデートが継続されることが発表されました。2.10の間にどう変わったのか?」という疑問に対する答えは、.96ガロンデコと.52ガロン、3Kスコープが減って、ダイナモローラーとカーボンローラーが増えた、です。どのくらい増えたのか、人気ブキに限らず使用率が...記事を読むブログ始めました色々と思うところがあり、ブログを始めることにしました。合言葉にして、気楽に書いていこうと思います。記事を読むキートップのノベルティを作ってみた話2月19日にノベルティカンファレンス2018で「キートップのノベルティを作ってみた話」というタイトルで発表しました。発表から時間が空いてしまいましたが、ブログに残しておきます。発表資料はこちらです。2018でMint60のスターターキットを購入して作りました。コメントをキャンセルメールアドレスが公開されることはありません。