結果
| 問題 |
No.5005 3-SAT
|
| ユーザー |
tomerun
|
| 提出日時 | 2022-04-29 14:32:25 |
| 言語 | Crystal (1.14.0) |
| 結果 |
AC
|
| 実行時間 | 1,580 ms / 2,000 ms |
| コード長 | 3,167 bytes |
| コンパイル時間 | 17,052 ms |
| 実行使用メモリ | 6,956 KB |
| スコア | 739 |
| 最終ジャッジ日時 | 2022-04-29 14:35:29 |
| 合計ジャッジ時間 | 180,778 ms |
|
ジャッジサーバーID (参考情報) |
judge13 / judge11 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 100 |
ソースコード
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 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
@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(N, -1)
@search_order = [0, 1, 2]
@dfs_count = 0
end
def solve(timelimit)
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()
# if res.score > best_res.score
# best_res = res
# best_loops = loops
# debug("score:#{best_res.score} at turn #{turn}")
# end
after_time = Time.utc.to_unix_ms
worst_time = {worst_time, after_time - before_time}.max
turn += 1
end
return @best_result
end
def solve_single
@ans.fill(-1)
@dfs_count = 0
dfs(0)
end
def dfs(pos)
if pos > @best_result.score
@best_result.score = pos
@best_result.bits[0, N] = @ans
debug("best_score:#{pos}")
end
if @dfs_count > 1000
return
end
if @terms[pos].any? { |t| @ans[t.var] == t.val }
dfs(pos + 1)
else
@dfs_count += 1
shuffle(@search_order)
3.times do |i|
t = @terms[pos][@search_order[i]]
if @ans[t.var] == -1
ok = true
@ans[t.var] = t.val
@var_pos[t.var].each do |ps|
p, v = ps
if p > pos && p <= @best_result.score && v != t.val
if @terms[p].all? { |nt| @ans[nt.var] == 1 - nt.val }
ok = false
break
end
end
end
if ok
dfs(pos + 1)
end
@ans[t.var] = -1
end
end
end
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
end
def main
solver = Solver.new
res = solver.solve(START_TIME + TL)
puts res
{% if flag?(:local) %}
STDERR.puts("score:#{res.score}")
{% end %}
end
main
tomerun