結果
問題 | No.5020 Averaging |
ユーザー | tomerun |
提出日時 | 2024-02-25 16:58:18 |
言語 | Crystal (1.11.2) |
結果 |
AC
|
実行時間 | 983 ms / 1,000 ms |
コード長 | 4,323 bytes |
コンパイル時間 | 11,200 ms |
コンパイル使用メモリ | 293,292 KB |
実行使用メモリ | 6,676 KB |
スコア | 84,197,895 |
最終ジャッジ日時 | 2024-02-25 17:01:16 |
合計ジャッジ時間 | 63,217 ms |
ジャッジサーバーID (参考情報) |
judge15 / judge13 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 983 ms
6,676 KB |
testcase_01 | AC | 982 ms
6,676 KB |
testcase_02 | AC | 982 ms
6,676 KB |
testcase_03 | AC | 982 ms
6,676 KB |
testcase_04 | AC | 982 ms
6,676 KB |
testcase_05 | AC | 982 ms
6,676 KB |
testcase_06 | AC | 982 ms
6,676 KB |
testcase_07 | AC | 982 ms
6,676 KB |
testcase_08 | AC | 983 ms
6,676 KB |
testcase_09 | AC | 982 ms
6,676 KB |
testcase_10 | AC | 982 ms
6,676 KB |
testcase_11 | AC | 982 ms
6,676 KB |
testcase_12 | AC | 983 ms
6,676 KB |
testcase_13 | AC | 982 ms
6,676 KB |
testcase_14 | AC | 982 ms
6,676 KB |
testcase_15 | AC | 982 ms
6,676 KB |
testcase_16 | AC | 983 ms
6,676 KB |
testcase_17 | AC | 981 ms
6,676 KB |
testcase_18 | AC | 983 ms
6,676 KB |
testcase_19 | AC | 983 ms
6,676 KB |
testcase_20 | AC | 982 ms
6,676 KB |
testcase_21 | AC | 982 ms
6,676 KB |
testcase_22 | AC | 982 ms
6,676 KB |
testcase_23 | AC | 983 ms
6,676 KB |
testcase_24 | AC | 982 ms
6,676 KB |
testcase_25 | AC | 983 ms
6,676 KB |
testcase_26 | AC | 983 ms
6,676 KB |
testcase_27 | AC | 982 ms
6,676 KB |
testcase_28 | AC | 982 ms
6,676 KB |
testcase_29 | AC | 982 ms
6,676 KB |
testcase_30 | AC | 982 ms
6,676 KB |
testcase_31 | AC | 982 ms
6,676 KB |
testcase_32 | AC | 983 ms
6,676 KB |
testcase_33 | AC | 982 ms
6,676 KB |
testcase_34 | AC | 983 ms
6,676 KB |
testcase_35 | AC | 983 ms
6,676 KB |
testcase_36 | AC | 982 ms
6,676 KB |
testcase_37 | AC | 982 ms
6,676 KB |
testcase_38 | AC | 982 ms
6,676 KB |
testcase_39 | AC | 983 ms
6,676 KB |
testcase_40 | AC | 983 ms
6,676 KB |
testcase_41 | AC | 982 ms
6,676 KB |
testcase_42 | AC | 982 ms
6,676 KB |
testcase_43 | AC | 982 ms
6,676 KB |
testcase_44 | AC | 983 ms
6,676 KB |
testcase_45 | AC | 982 ms
6,676 KB |
testcase_46 | AC | 982 ms
6,676 KB |
testcase_47 | AC | 982 ms
6,676 KB |
testcase_48 | AC | 983 ms
6,676 KB |
testcase_49 | AC | 982 ms
6,676 KB |
ソースコード
START_TIME = Time.utc.to_unix_ms TL = (ENV["TL"]? || 980).to_i PART = (ENV["PART"]? || 10).to_i IC = (ENV["IC"]? || 1).to_f FC = (ENV["FC"]? || 10).to_f N = 45 MED = 500_000_000_000_000_000i64 RND = Random.new(3) alias PI = Tuple(Int32, Int32) macro debug(msg) {% if flag?(:local) %} STDERR.puts({{msg}}) {% end %} end macro debugf(format_string, *args) {% if flag?(:local) %} STDERR.printf({{format_string}}, {{*args}}) {% end %} end def crash(msg, caller_line = __LINE__) puts "[ERROR] line #{caller_line}: #{msg}" exit end macro assert(cond, msg = "", caller_line = __LINE__) {% if flag?(:local) %} if !({{cond}}) crash({{msg}}, {{caller_line}}) end {% end %} end class Result property :pairs, :v0, :v1 getter :score @score : Float64 def initialize(@pairs : Array(PI), @v0 : Int64, @v1 : Int64) @score = Math.log10({(@v0 - MED).abs, (@v1 - MED).abs}.max + 1) end def to_s(io) io << "#{@pairs.size}\n" << @pairs.map { |p| {p[0] + 1, p[1] + 1}.join(" ") }.join("\n") end end RES_EMPTY = Result.new([] of PI, 0u64, 0u64) class Solver def initialize(@a : Array(Int64), @b : Array(Int64)) end def solve(timelimit) av = @a.dup bv = @b.dup level = N.times.to_a.map { |i| i + 1 } level[-1] -= 1 N.times do |i| level.swap(i, RND.rand(N - i) + i) end sum_a = N.times.sum { |i| @a[i] >> level[i] } - MED sum_b = N.times.sum { |i| @b[i] >> level[i] } - MED # cost = {(sum_a - med).abs, (sum_b - med).abs}.max cost = (sum_a).to_f ** 2 + (sum_b).to_f ** 2 best_cost = cost best_level = level.dup debug("initial_cost:#{cost} #{sum_a} #{sum_b}") turn = 0 cooler = IC init_time = Time.utc.to_unix_ms while true turn += 1 if (turn & 0xFFF) == 0 cur_time = Time.utc.to_unix_ms if cur_time > timelimit debug("turn:#{turn}\n") break end ratio = (cur_time - init_time) / (timelimit - init_time) cooler = (1.0 - ratio) * IC + ratio * FC end v0 = RND.rand(N) v1 = RND.rand(N - 1) v1 += 1 if v1 >= v0 while level[v0] == level[v1] v0 = RND.rand(N) v1 = RND.rand(N - 1) v1 += 1 if v1 >= v0 end na = sum_a + (@a[v0] >> level[v1]) - (@a[v0] >> level[v0]) + (@a[v1] >> level[v0]) - (@a[v1] >> level[v1]) nb = sum_b + (@b[v0] >> level[v1]) - (@b[v0] >> level[v0]) + (@b[v1] >> level[v0]) - (@b[v1] >> level[v1]) # nc = {(na - med).abs, (nb - med).abs}.max nc = (na).to_f ** 2 + (nb).to_f ** 2 if (accept(nc, cost, cooler) || (turn & 0x3FFFF) == 0) cost = nc level.swap(v0, v1) sum_a = na sum_b = nb if nc < best_cost debug("best_cost:#{nc} turn:#{turn} diff_a:#{sum_a} diff_b:#{sum_b}") best_cost = nc best_level = level.dup end end end ords = Array.new(N + 1) { [] of Int32 } N.times { |i| ords[N - 1 - best_level[i]] << i } ans = [] of PI la = @a.dup lb = @b.dup ords.size.times do |i| ord = ords[i] while ord.size > 1 i0 = ord.pop i1 = ord.pop ans << {i0, i1} ords[i + 1] << {i0, i1}.min sa = (la[i0] + la[i1]) // 2 sb = (lb[i0] + lb[i1]) // 2 la[i0] = la[i1] = sa lb[i0] = lb[i1] = sb end end return Result.new(ans, la[0], lb[0]) end def accept(new_cost, old_cost, cooler) return true if new_cost <= old_cost # return false # diff = new_cost - old_cost diff = Math.log10(new_cost) - Math.log10(old_cost) v = -diff * cooler return false if v < -8 return RND.rand < Math.exp(v) end end def main gets a = [] of Int64 b = [] of Int64 N.times do |i| u, v = read_line.split.map(&.to_i64) a << u b << v end solver = Solver.new(a, b) best_res = Result.new([] of PI, a[0], b[0]) part = PART part.times do |i| res = solver.solve(START_TIME + TL * (i + 1) // part) if res.score < best_res.score best_res = res end end puts best_res {% if flag?(:local) %} STDERR.printf("raw:%7f score:%d\n", best_res.score, (2000000 - 100000 * best_res.score).floor) {% end %} end main