結果
問題 | No.5017 Tool-assisted Shooting |
ユーザー |
![]() |
提出日時 | 2023-07-16 15:31:21 |
言語 | Crystal (1.14.0) |
結果 |
AC
|
実行時間 | 87 ms / 2,000 ms |
コード長 | 5,018 bytes |
コンパイル時間 | 21,185 ms |
コンパイル使用メモリ | 256,516 KB |
実行使用メモリ | 24,480 KB |
スコア | 4,068,126 |
平均クエリ数 | 1000.00 |
最終ジャッジ日時 | 2023-07-16 15:31:54 |
合計ジャッジ時間 | 32,356 ms |
ジャッジサーバーID (参考情報) |
judge13 / judge14 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 100 |
ソースコード
START_TIME = Time.utc.to_unix_msTL = (ENV["TL"]? || 1000).to_iINF = 1 << 28H = 60W = 25RND = Random.new(2)macro debug(msg){% if flag?(:trace) %}STDERR.puts({{msg}}){% end %}endmacro debugf(format_string, *args){% if flag?(:trace) %}STDERR.printf({{format_string}}, {{*args}}){% end %}enddef crash(msg, caller_line = __LINE__)STDERR.puts "[ERROR] line #{caller_line}: #{msg}"exitendmacro assert(cond, msg = "", caller_line = __LINE__){% if flag?(:local) %}if !({{cond}})crash({{msg}}, {{caller_line}})end{% end %}endrecord Spawn, h : Int32, p : Int32, x : Int32class Enemyproperty :hgetter :pdef initialize(@h : Int32, @p : Int32)endendclass OnlineJudgedef inputn = read_line.to_ireturn nil if n == -1return Array.new(n) doh, p, x = read_line.split.map(&.to_i)Spawn.new(h, p, x)endenddef output(dir)puts "SRL"[dir]STDOUT.flushendendclass LocalJudge@p : Array(Int32)def initialize@p = read_line.split.map(&.to_i)@enemies = Array(Array(Enemy?)).new(W) { Array(Enemy?).new(H, nil) }@player = 12@exp = 0@turn = 0@defeat = falseenddef inputW.times do |i|@enemies[i][0..(H - 2)] = @enemies[i][1..]@enemies[i][-1] = nilendif @enemies[@player][0]@defeat = trueendif @defeatdebug("defeat at turn #{@turn}")return nilendn = read_line.to_iret = [] of Spawnn.times doh, p, x = read_line.split.map(&.to_i)@enemies[x][H - 1] = Enemy.new(h, p)ret << Spawn.new(h, p, x)end@turn += 1return retenddef output(dir)@player += dir + W@player %= Wif @enemies[@player][0]@defeat = trueelse1.upto(H - 1) do |i|if e = @enemies[@player][i]e.h -= @exp // 100 + 1if e.h <= 0@exp += e.p@enemies[@player][i] = nilendbreakendendendenddef printprintf("score=%d\n", @exp)endend###################### end of template/lib#####################maindef mainjudge = OnlineJudge.new{% if flag?(:local) %}judge = LocalJudge.new{% end %}solver = Solver.new(judge)solver.solve{% if flag?(:local) %}judge.as(LocalJudge).print{% end %}endclass Solver(Judge)def initialize(@judge : Judge)@es = Array(Array(Enemy?)).new(W) { Array(Enemy?).new(H, nil) }@px = 12@exp = 0@atk = 1@turn = 0@spawn_cnt = Array(Int32).new(W, 0)enddef solve1000.times doss = @judge.inputif !ssdebug("score:#{@exp}")returnendW.times do |x|@es[x].rotate!(1)@es[x][H - 1] = nilendss.each do |s|@es[s.x][H - 1] = Enemy.new(s.h, s.p)@spawn_cnt[s.x] += 1endmove = select_move()@px = mv(@px, move)if @es[@px][0].nil?1.upto(H - 1) do |y|if e = @es[@px][y]debug("attack (#{@px},#{y}) #{e.h}->#{e.h - @atk}")e.h -= @atkif e.h <= 0@exp += e.p@atk = 1 + @exp // 100@es[@px][y] = nilendbreakendendend@judge.output(move)@turn += 1enddebug("score:#{@exp}")enddef spawn_cnt_bonus(x)p = (@spawn_cnt[x] + 4) / (@turn + 100)return p * 1enddef select_movedebug("x:#{@px}")best_v = 0.0best_move = 01.upto(H - 1) do |ey|if e = @es[@px][ey]need = (e.h + @atk - 1) // @atkif need <= ey - 0eff = e.p / (0 + need + 1)eff += spawn_cnt_bonus(@px)if eff > best_vbest_v = effbest_move = 0debug("best_v:#{eff} #{@px} 0 0")endendbreakendend{-1, 1}.each do |move|nx = mv(@px, move)next if @es[nx][0] || @es[nx][1] && @es[nx][1].not_nil!.h > @atkny = 0while nx != @px && ny < H - 3(ny + 1).upto(H - 1) do |ey|if e = @es[nx][ey]need = (e.h + @atk - 1) // @atkif need <= ey - nyeff = e.p / (ny + need + 1)eff += spawn_cnt_bonus(nx)if eff > best_vbest_v = effbest_move = movedebug("best_v:#{eff} #{nx} #{ny} #{move}")endendbreakendendny += 1if @es[nx][ny]breakendnnx = mv(nx, move)next if @es[nnx][ny] || @es[nnx][ny + 1] && @es[nnx][ny + 1].not_nil!.h > @atknx = nnxendendreturn best_moveenddef mv(x, d)x += dif x == -1return W - 1elsif x == Wreturn 0elsereturn xendendend