LoginSignup
0
0

More than 1 year has passed since last update.

問題解決力を鍛える!アルゴリズムとデータ構造を読み進めていく中で、二分探索法でAtCoderの射撃王という問題が出題されていました。
C++で解答が書かれていたがいまいちピンと来なかったので、Rubyで自分なりに解釈しながら書き換えていきました。
実際にACもらったので、コメントで説明してあるRubyコードを載せます。

n = gets.chomp.to_i
hs = Array.new(n) {gets.chomp.split(' ').map(&:to_i)}

#bsearchメソッドで二分探索開始(ブロックの評価結果が true になる最初の要素を返すか、nil を返す)
ans = (1..10**15).bsearch do |v|
  # v は目標高度のデッドラインとなる
  timetable = Array.new(n, 0)
  flug = true
  hs.each do |h, s|
    #(v-h)/s で、風船がデッドラインに達するまでの時間
    #風船がデッドラインに達するまでの時間と 最低限待てる時間を比べ、小さい方を選ぶ
    second = [(v-h)/s, n-1].min
    if second < 0
        #風船のデッドラインまでの時間が負(既にデッドラインに達している)ならfalseにする
        flug = false 
    else
        ##まだ正(デッドラインに達するまで時間がある)なら割らなきゃいけない時間の配列に+=1
        timetable[second] += 1
    end
  end

  shootable = 0
  #shootable = その時間までで割れる風船の数
  n.times do |j|
    shootable += 1
    #もしその時間までで割れる風船の数よりも多くの風船をその時間内に割らなきゃいけないなら、flug=false
    flug = false if shootable < timetable[j]
    #そうでないなら、割った数だけ引く
    shootable -= timetable[j]
  end
  #flug = true ならvで与えたデッドライン以内で割れるということ
  flug
end

#falseとtrueの境目のansが与えられる
p ans
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0