結果

問題 No.4 おもりと天秤
ユーザー らっしー(raccy)らっしー(raccy)
提出日時 2015-08-22 21:05:19
言語 Ruby
(3.3.0)
結果
AC  
実行時間 947 ms / 5,000 ms
コード長 2,324 bytes
コンパイル時間 197 ms
コンパイル使用メモリ 11,388 KB
実行使用メモリ 22,044 KB
最終ジャッジ日時 2023-09-08 16:23:54
合計ジャッジ時間 4,132 ms
ジャッジサーバーID
(参考情報)
judge12 / judge13
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 81 ms
15,052 KB
testcase_01 AC 81 ms
15,272 KB
testcase_02 AC 81 ms
15,164 KB
testcase_03 AC 82 ms
15,304 KB
testcase_04 AC 81 ms
15,348 KB
testcase_05 AC 80 ms
15,172 KB
testcase_06 AC 79 ms
15,168 KB
testcase_07 AC 79 ms
15,248 KB
testcase_08 AC 80 ms
15,092 KB
testcase_09 AC 82 ms
15,108 KB
testcase_10 AC 79 ms
15,148 KB
testcase_11 AC 81 ms
15,168 KB
testcase_12 AC 81 ms
15,092 KB
testcase_13 AC 78 ms
15,136 KB
testcase_14 AC 80 ms
15,052 KB
testcase_15 AC 79 ms
15,096 KB
testcase_16 AC 78 ms
15,140 KB
testcase_17 AC 79 ms
15,196 KB
testcase_18 AC 947 ms
22,044 KB
testcase_19 AC 79 ms
15,252 KB
testcase_20 AC 79 ms
15,164 KB
testcase_21 AC 80 ms
15,160 KB
testcase_22 AC 80 ms
15,192 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
Syntax OK

ソースコード

diff #

# coding: utf-8
# おもりのリストのクラス
class Omoris
  # 初期化時にソートする。
  def initialize(list)
    @list = list.sort
    # その前での合計リスト
    @sum_list = @list.inject([]) do |m, i|
      m << m.last.to_i + i
    end
    # 結果のキャッシュ
    @cache = {}
  end

  # おもりの合計を返す。
  def sum(index = -1)
    @sum_list[index]
  end

  # end番目以前の組み合わせで合計がtargetになるか?
  def check(target, last)
    if @cache.has_key?([target, last])
      return @cache[[target, last]]
    end
    # 0なら合致しているのでOK
    return true if target == 0
    # 最後の前まで調べる。
    (0..last).to_a.reverse.each do |i|
      if target > @sum_list[i]
        # 全部足しても届かない
        @cache[[target, last]] = false
        return false
      elsif target == @sum_list[i]
        # 全部足すと一致
        @cache[[target, last]] = true
        return true
      elsif i < last && @list[i + 1] == @list[i]
        # 2回目以降で前と一緒なら調べる必要なし。
        next
      elsif target < @list[i]
        # 越えちゃったので次を調べる。
        next
      else
        # 少ないときはtargetから今の分を減らして、さらにcheckする。
        if check(target - @list[i], i - 1)
          # 合致したのでOK。
          @cache[[target, last]] = true
          return true
        else
          # あわなくても次を調べる。
          next
        end
      end
    end
    # 一致なし
    @cache[[target, last]] = false
    return false
  end

  # 重りのインデックス
  def [](index)
    @list[index]
  end

  # 重りの数
  def size
    @list.size
  end
end

# 1行目はRubyでは不要。
gets
# 数字のリストを取得。
omoris = Omoris.new(gets.split.map(&:to_i))
sum = omoris.sum
# 合計が偶数で無いと組み合わせは無い。
# 2個以上重りが無いと組み合わせは無い。
# 一番大きい重りが半分以下で無いと組み合わせは無い。
# 合計の半分の組み合わせをチェックする。
if sum.even? &&
    omoris.size > 1 &&
    omoris[-1] <= sum / 2 &&
    omoris.check((sum / 2 - omoris[-1]), omoris.size - 2)
  puts "possible"
else
  puts "impossible"
end
0