Hatena::Grouptopcoder

hotpepsiの練習帳

2013-05-19

Google Code Jam 2013 Round 1B

18:17

A. Osmos

問題

  • 物体を吸収していくゲーム
  • N個の物体と、手持ちの物体の重さが与えられる
  • 手持ちの物体より軽い物体は吸収でき、その重さが加わる
  • 場に任意の重さの物体を追加するか、または、場の任意の物体を除外することができる
  • 全ての物体を吸収するために必要な、追加または除外の操作回数を求める

方針 (small, large)

  • 貪欲
  • N個全てを除外するのが最大値
  • 1個ずつ吸収していく
  • 自重より軽いものがない場合は、自重の-1の重さのものを追加して、追加回数をカウントしておく
  • 残りを全て除外したと仮定して、最小値を更新する
  • https://github.com/firewood/topcoder/blob/master/gcj_2013/R1B_A.cpp

B. Falling Diamonds

問題

  • ダイアモンドが上から落ちてくる
  • 下にダイアモンドが存在する場合、左か右に積もっていく
  • おおむね三角形になる
  • 落ちてくる総数と、座標(X,Y)が与えられる
  • その座標にダイアモンドが積もる確率を求める

方針 (small)

  • (終了後)
  • 1個,5個,9個...と、4x+1個ずつ、三角形に積もる
  • 頂点を除き、片側に積もる最大の個数は|X|+|Y|
  • 三角形の内側なら1.0、完全に外側なら0.0、その間なら計算する
  • 両側にlength個ずつ落ちる場所があり、N個落ちてくるときの確率を求める
  • 左に落ちる場合を0、右に落ちる場合を1として、Nビットを全列挙して足す
  • ただし、片側にlength個以上落ちた場合は、反対側に落ちたものとして計算する
  • 落ちる個数はpopcount(x)+max(0,popcount(~x)-length)
  • https://github.com/firewood/topcoder/blob/master/gcj_2013/R1B_B_s.cpp

方針 (large)

  • (終了後)
  • kmjpさんのブログを読む
  • DPで計算できるっぽい
  • i個落ちてきたときの確率テーブルがあり、i+1個目が落ちてきたとする
  • j個存在するが確率Pとする
  • 1/2でこちらに落ちない(反対側に落ちる)ので、dp[i+1][j]に0.5×Pを加える
  • 1/2で落ちるので、dp[i+1][j+1]に0.5×Pを加える
  • すでにlength個落ちている場合は、反対側に落ちるので、dp[i+1][length]にはdp[i][length]を加える
  • 反対側にlength個落ちている場合は、こちらに落ちるので、dp[i+1][length+1]にdp[i][length]を加える
  • length=6のときのテーブルは以下の通り
i0個1個2個3個4個5個6個7個
00.5000.500
10.2500.5000.250
20.1250.3750.3750.125
30.0630.2500.3750.2500.063
40.0310.1560.3130.3130.1560.031
50.0160.0940.2340.3130.2340.0940.016
60.0000.0630.1640.2730.2730.1640.0630.000
70.0000.0000.1450.2190.2730.2190.1450.0000.000
80.0000.0000.0000.2540.2460.2460.2540.0000.0000.000

結果

A small+large 22pt 1584th/4678

Bはビット列挙を思いつかず。面白い問題だった。

トラックバック - https://topcoder-g-hatena-ne-jp.jag-icpc.org/firewood/20130519