結果

問題 No.3459 Defeat Slimes
コンテスト
ユーザー Nanashi.
提出日時 2026-02-28 15:29:24
言語 Ruby
(4.0.1)
コンパイル:
ruby -w -c _filename_
実行:
ruby _filename_
結果
AC  
実行時間 1,577 ms / 3,000 ms
コード長 3,950 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 393 ms
コンパイル使用メモリ 9,216 KB
実行使用メモリ 39,808 KB
最終ジャッジ日時 2026-02-28 15:29:58
合計ジャッジ時間 30,446 ms
ジャッジサーバーID
(参考情報)
judge3 / judge7
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 30
権限があれば一括ダウンロードができます
コンパイルメッセージ
Main.rb:5: warning: 'frozen_string_literal' is ignored after any tokens
Main.rb:27: warning: ambiguous first argument; put parentheses or a space even after `-` operator
Syntax OK

ソースコード

diff #
raw source code

# frozen_string_literal: true
# This file is expanded by nanacl.

main = -> do # =================================================================
# frozen_string_literal: true
# require "ac-library-rb/priority_queue" # (expanded: L49)

in_n, in_y, in_z = gets.chomp.split.map(&:to_i)
in_clx = in_n.times.map { gets.chomp.split.map(&:to_i) }

pq = AcLibraryRb::PriorityQueue.new { |a, b| a[2] > b[2] }

clx = in_clx.dup
clx << [1, 10**20, 0]
clx.sort_by!{|c,l,x|l}

level = in_y
count = 0
until level >= in_z
  while clx[0][1] <= level
    pq << clx.shift
  end
  next_target = [clx[0][1], in_z].min

  current = pq.get
  if current.nil?
    puts -1
    exit
  end

  used = if current[0] * current[2] >= next_target - level
    (next_target - level).ceildiv(current[2])
  else
    current[0]
  end
  count += used
  level += current[2] * used
  current[0] -= used
  if current[0] == 0
    pq.pop
  end
end

puts count

end # --------------------------------------------------------------------------

# === dependencies -------------------------------------------------------------
# == ac-library-rb/priority_queue from main ------------------------------------
module AcLibraryRb
  # Priority Queue
  # Reference: https://github.com/python/cpython/blob/main/Lib/heapq.py
  class PriorityQueue
    # By default, the priority queue returns the maximum element first.
    # If a block is given, the priority between the elements is determined with it.
    # For example, the following block is given, the priority queue returns the minimum element first.
    # `PriorityQueue.new { |x, y| x < y }`
    #
    # A heap is an array for which a[k] <= a[2*k+1] and a[k] <= a[2*k+2] for all k, counting elements from 0.
    def initialize(array = [], &comp)
      @heap = array
      @comp = comp || proc { |x, y| x > y }
      heapify
    end

    def self.max(array)
      new(array)
    end

    def self.min(array)
      new(array){ |x, y| x < y }
    end

    def self.[](*array, &comp)
      new(array, &comp)
    end

    attr_reader :heap
    alias to_a heap

    # Push new element to the heap.
    def push(item)
      shift_down(0, @heap.push(item).size - 1)
      self
    end

    alias << push
    alias append push

    # Pop the element with the highest priority.
    def pop
      latest = @heap.pop
      return latest if empty?

      ret_item = heap[0]
      heap[0] = latest
      shift_up(0)
      ret_item
    end

    # Get the element with the highest priority.
    def get
      @heap[0]
    end

    alias top get
    alias first get

    # Returns true if the heap is empty.
    def empty?
      @heap.empty?
    end

    def size
      @heap.size
    end

    def to_s
      "<#{self.class}: @heap:(#{heap.join(', ')}), @comp:<#{@comp.class} #{@comp.source_location.join(':')}>>"
    end

    private

    def heapify
      (@heap.size / 2 - 1).downto(0) { |i| shift_up(i) }
    end

    def shift_up(pos)
      end_pos = @heap.size
      start_pos = pos
      new_item = @heap[pos]
      left_child_pos = 2 * pos + 1

      while left_child_pos < end_pos
        right_child_pos = left_child_pos + 1
        if right_child_pos < end_pos && @comp.call(@heap[right_child_pos], @heap[left_child_pos])
          left_child_pos = right_child_pos
        end
        # Move the higher priority child up.
        @heap[pos] = @heap[left_child_pos]
        pos = left_child_pos
        left_child_pos = 2 * pos + 1
      end
      @heap[pos] = new_item
      shift_down(start_pos, pos)
    end

    def shift_down(star_pos, pos)
      new_item = @heap[pos]
      while pos > star_pos
        parent_pos = (pos - 1) >> 1
        parent = @heap[parent_pos]
        break if @comp.call(parent, new_item)

        @heap[pos] = parent
        pos = parent_pos
      end
      @heap[pos] = new_item
    end
  end

  HeapQueue = PriorityQueue
end


# ==============================================================================

main.call
0