結果
問題 | No.5005 3-SAT |
ユーザー | tomerun |
提出日時 | 2022-04-29 16:54:10 |
言語 | Crystal (1.11.2) |
結果 |
AC
|
実行時間 | 1,712 ms / 2,000 ms |
コード長 | 5,589 bytes |
コンパイル時間 | 20,978 ms |
実行使用メモリ | 6,948 KB |
スコア | 102,386 |
最終ジャッジ日時 | 2022-04-29 16:56:48 |
合計ジャッジ時間 | 154,844 ms |
ジャッジサーバーID (参考情報) |
judge11 / judge14 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,339 ms
5,820 KB |
testcase_01 | AC | 1,631 ms
5,780 KB |
testcase_02 | AC | 1,294 ms
5,712 KB |
testcase_03 | AC | 1,208 ms
5,828 KB |
testcase_04 | AC | 1,301 ms
5,708 KB |
testcase_05 | AC | 1,089 ms
5,784 KB |
testcase_06 | AC | 1,228 ms
5,796 KB |
testcase_07 | AC | 1,229 ms
5,748 KB |
testcase_08 | AC | 1,155 ms
5,660 KB |
testcase_09 | AC | 1,000 ms
5,740 KB |
testcase_10 | AC | 1,230 ms
5,688 KB |
testcase_11 | AC | 1,177 ms
5,860 KB |
testcase_12 | AC | 1,389 ms
5,696 KB |
testcase_13 | AC | 1,567 ms
5,820 KB |
testcase_14 | AC | 1,236 ms
5,828 KB |
testcase_15 | AC | 1,146 ms
5,716 KB |
testcase_16 | AC | 1,050 ms
5,796 KB |
testcase_17 | AC | 1,002 ms
5,696 KB |
testcase_18 | AC | 1,602 ms
5,724 KB |
testcase_19 | AC | 859 ms
5,856 KB |
testcase_20 | AC | 1,099 ms
5,708 KB |
testcase_21 | AC | 1,447 ms
5,768 KB |
testcase_22 | AC | 1,238 ms
5,732 KB |
testcase_23 | AC | 1,205 ms
5,856 KB |
testcase_24 | AC | 1,381 ms
5,740 KB |
testcase_25 | AC | 1,278 ms
5,860 KB |
testcase_26 | AC | 1,371 ms
5,668 KB |
testcase_27 | AC | 1,098 ms
5,648 KB |
testcase_28 | AC | 1,269 ms
5,744 KB |
testcase_29 | AC | 1,279 ms
5,676 KB |
testcase_30 | AC | 797 ms
5,632 KB |
testcase_31 | AC | 1,175 ms
5,756 KB |
testcase_32 | AC | 1,055 ms
5,812 KB |
testcase_33 | AC | 1,165 ms
5,816 KB |
testcase_34 | AC | 1,583 ms
5,652 KB |
testcase_35 | AC | 1,222 ms
5,760 KB |
testcase_36 | AC | 1,471 ms
5,708 KB |
testcase_37 | AC | 1,445 ms
5,668 KB |
testcase_38 | AC | 1,062 ms
5,716 KB |
testcase_39 | AC | 836 ms
5,776 KB |
testcase_40 | AC | 1,194 ms
5,736 KB |
testcase_41 | AC | 1,259 ms
5,800 KB |
testcase_42 | AC | 1,248 ms
5,672 KB |
testcase_43 | AC | 1,009 ms
5,712 KB |
testcase_44 | AC | 1,362 ms
5,664 KB |
testcase_45 | AC | 1,317 ms
5,696 KB |
testcase_46 | AC | 800 ms
5,728 KB |
testcase_47 | AC | 1,051 ms
5,712 KB |
testcase_48 | AC | 1,337 ms
5,744 KB |
testcase_49 | AC | 1,033 ms
5,728 KB |
testcase_50 | AC | 1,417 ms
5,640 KB |
testcase_51 | AC | 1,294 ms
5,744 KB |
testcase_52 | AC | 1,712 ms
5,688 KB |
testcase_53 | AC | 1,203 ms
5,732 KB |
testcase_54 | AC | 1,458 ms
5,696 KB |
testcase_55 | AC | 1,367 ms
5,796 KB |
testcase_56 | AC | 1,240 ms
5,748 KB |
testcase_57 | AC | 867 ms
5,688 KB |
testcase_58 | AC | 1,308 ms
5,688 KB |
testcase_59 | AC | 1,173 ms
5,716 KB |
testcase_60 | AC | 1,482 ms
5,792 KB |
testcase_61 | AC | 1,328 ms
5,700 KB |
testcase_62 | AC | 1,023 ms
5,712 KB |
testcase_63 | AC | 1,019 ms
5,720 KB |
testcase_64 | AC | 1,233 ms
5,732 KB |
testcase_65 | AC | 1,058 ms
5,676 KB |
testcase_66 | AC | 1,290 ms
5,740 KB |
testcase_67 | AC | 1,093 ms
5,736 KB |
testcase_68 | AC | 1,517 ms
6,948 KB |
testcase_69 | AC | 827 ms
5,628 KB |
testcase_70 | AC | 1,112 ms
5,664 KB |
testcase_71 | AC | 1,195 ms
5,756 KB |
testcase_72 | AC | 1,072 ms
5,888 KB |
testcase_73 | AC | 797 ms
5,708 KB |
testcase_74 | AC | 1,192 ms
5,744 KB |
testcase_75 | AC | 1,003 ms
5,696 KB |
testcase_76 | AC | 1,409 ms
6,124 KB |
testcase_77 | AC | 1,435 ms
5,720 KB |
testcase_78 | AC | 1,360 ms
5,656 KB |
testcase_79 | AC | 1,251 ms
5,828 KB |
testcase_80 | AC | 1,625 ms
5,696 KB |
testcase_81 | AC | 1,483 ms
5,628 KB |
testcase_82 | AC | 1,103 ms
5,664 KB |
testcase_83 | AC | 1,242 ms
5,676 KB |
testcase_84 | AC | 1,169 ms
5,760 KB |
testcase_85 | AC | 1,312 ms
5,672 KB |
testcase_86 | AC | 1,207 ms
5,836 KB |
testcase_87 | AC | 1,154 ms
5,700 KB |
testcase_88 | AC | 1,496 ms
5,732 KB |
testcase_89 | AC | 1,238 ms
5,672 KB |
testcase_90 | AC | 1,175 ms
5,748 KB |
testcase_91 | AC | 1,216 ms
5,660 KB |
testcase_92 | AC | 1,460 ms
5,744 KB |
testcase_93 | AC | 1,366 ms
5,692 KB |
testcase_94 | AC | 1,453 ms
5,700 KB |
testcase_95 | AC | 1,021 ms
5,856 KB |
testcase_96 | AC | 1,537 ms
5,708 KB |
testcase_97 | AC | 1,276 ms
5,824 KB |
testcase_98 | AC | 886 ms
5,712 KB |
testcase_99 | AC | 1,412 ms
5,672 KB |
ソースコード
START_TIME = Time.utc.to_unix_ms TL = 1580 N = 2048 M = 256 INF = 1 << 29 RND = Random.new(2) macro debug(msg) {% if flag?(:trace) %} STDERR.puts({{msg}}) {% end %} end macro debugf(format_string, *args) {% if flag?(:trace) %} STDERR.printf({{format_string}}, {{*args}}) {% end %} end class IndexSet getter :upper def initialize(@upper : Int32) @que = [] of Int32 @pos = Array(Int32).new(@upper, -1) end def add(v) if @pos[v] == -1 @pos[v] = @que.size @que << v end end def remove(v) p = @pos[v] b = @que[-1] @que[p] = b @que.pop @pos[b] = p @pos[v] = -1 end def get_random @que[RND.rand(@que.size)] end def size @que.size end def to_s(io) @que.to_s(io) end end class Result property :bits, :score def initialize(@bits : Array(Int32), @score : Int32) end def to_s(io) io << @bits.map { |v| v == -1 ? 0 : v }.reverse.join end end struct Cond getter :var, :val def initialize(@var : Int32, @val : Int32) end end alias Term = Tuple(Cond, Cond, Cond) class Solver def initialize(@timelimit : Int64) @terms = Array(Term).new(N) do a, b, c, p, q, r = read_line.split.map(&.to_i) {Cond.new(a, p), Cond.new(b, q), Cond.new(c, r)} end @var_pos = Array(Array(Tuple(Int32, Int32))).new(M) { [] of Tuple(Int32, Int32) } N.times do |i| 3.times do |j| term = @terms[i][j] @var_pos[term.var] << {i, term.val} end end @best_result = Result.new(Array.new(M, -1), 0) @ans = Array(Int32).new(M, -1) @search_order = [0, 1, 2] @dfs_count = 0 @eval = Array(Int32).new(3, 0) @ok_count = Array(Int32).new(N, 0) @ng_count = Array(Int32).new(N, 0) @pass = Array(Bool).new(N) do |i| ts = @terms[i] [[0, 1], [1, 2], [2, 0]].any? { |ps| ts[ps[0]].var == ts[ps[1]].var && ts[ps[0]].var != ts[ps[1]].var } end end def solve start_time = Time.utc.to_unix_ms before_time = start_time solve_single() after_time = Time.utc.to_unix_ms worst_time = after_time - before_time turn = 0 while true before_time = after_time if before_time + worst_time > @timelimit debug("turn:#{turn} worst_time:#{worst_time}") break end solve_single() after_time = Time.utc.to_unix_ms worst_time = {worst_time, after_time - before_time}.max turn += 1 end STDERR.puts("validate_score:#{score(@best_result.bits)}") return @best_result end def solve_single @ans.fill(-1) @dfs_count = 0 @ok_count.fill(0) # @ng_count.fill(0) pos = 0 while pos < N if try_next(pos) while pos < N && @ok_count[pos] > 0 pos += 1 end if pos > @best_result.score @best_result.score = pos @best_result.bits[0, M] = @ans debug("best_score:#{pos}") end # if score(@ans) != pos # debug("validate_score:#{score(@ans)} score:#{pos}") # exit # end else break end end end def try_next(pos) shuffle(@search_order) 3.times do |i| t = @terms[pos][@search_order[i]] if @ans[t.var] == -1 @ans[t.var] = t.val @var_pos[t.var].each do |ps| p, v = ps if v == t.val @ok_count[p] += 1 # else # @ng_count[p] += 1 end end return true end end 1000.times do set = IndexSet.new(N) set.add(pos) @dfs_count = 0 if try_dfs(pos, set) return true end end return false end def try_dfs(pos, set) # debug("try_dfs:#{pos} #{set}") if set.size == 0 return true end if @dfs_count > 20 || set.size > 10 return false end cur = set.get_random shuffle(@search_order) tc = 0 3.times do |i| t = @terms[cur][@search_order[i]] old = @ans[t.var] @ans[t.var] = t.val @var_pos[t.var].each do |ps| p, v = ps if v == t.val @ok_count[p] += 1 # @ng_count[p] -= 1 if p <= pos && @ok_count[p] == 1 set.remove(p) end elsif old != -1 @ok_count[p] -= 1 # @ng_count[p] += 1 if p <= pos && @ok_count[p] == 0 set.add(p) end end # debug("@ok_count[#{p}]=#{@ok_count[p]}") # debug("@ng_count[#{p}]=#{@ng_count[p]}") end tc += 1 if tc == 2 @dfs_count += 1 end if try_dfs(pos, set) return true end @ans[t.var] = old @var_pos[t.var].each do |ps| p, v = ps if v == t.val @ok_count[p] -= 1 # @ng_count[p] += 1 if p <= pos && @ok_count[p] == 0 set.add(p) end elsif old != -1 @ok_count[p] += 1 # @ng_count[p] -= 1 if p <= pos && @ok_count[p] == 1 set.remove(p) end end end end return false end def shuffle(a) (a.size - 1).times do |i| pos = RND.rand(a.size - i) + i a[i], a[pos] = a[pos], a[i] end end def score(ans) N.times do |i| if @terms[i].all? { |t| ans[t.var] != t.val } return i end end return N end end def main solver = Solver.new(START_TIME + TL) res = solver.solve puts res {% if flag?(:local) %} STDERR.puts("final_score:#{res.score}") {% end %} end main