結果

問題 No.5017 Tool-assisted Shooting
ユーザー tomerun
提出日時 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
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

START_TIME = Time.utc.to_unix_ms
TL = (ENV["TL"]? || 1000).to_i
INF = 1 << 28
H = 60
W = 25
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
def crash(msg, caller_line = __LINE__)
STDERR.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
record Spawn, h : Int32, p : Int32, x : Int32
class Enemy
property :h
getter :p
def initialize(@h : Int32, @p : Int32)
end
end
class OnlineJudge
def input
n = read_line.to_i
return nil if n == -1
return Array.new(n) do
h, p, x = read_line.split.map(&.to_i)
Spawn.new(h, p, x)
end
end
def output(dir)
puts "SRL"[dir]
STDOUT.flush
end
end
class 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 = false
end
def input
W.times do |i|
@enemies[i][0..(H - 2)] = @enemies[i][1..]
@enemies[i][-1] = nil
end
if @enemies[@player][0]
@defeat = true
end
if @defeat
debug("defeat at turn #{@turn}")
return nil
end
n = read_line.to_i
ret = [] of Spawn
n.times do
h, p, x = read_line.split.map(&.to_i)
@enemies[x][H - 1] = Enemy.new(h, p)
ret << Spawn.new(h, p, x)
end
@turn += 1
return ret
end
def output(dir)
@player += dir + W
@player %= W
if @enemies[@player][0]
@defeat = true
else
1.upto(H - 1) do |i|
if e = @enemies[@player][i]
e.h -= @exp // 100 + 1
if e.h <= 0
@exp += e.p
@enemies[@player][i] = nil
end
break
end
end
end
end
def print
printf("score=%d\n", @exp)
end
end
#####################
# end of template/lib
#####################
main
def main
judge = OnlineJudge.new
{% if flag?(:local) %}
judge = LocalJudge.new
{% end %}
solver = Solver.new(judge)
solver.solve
{% if flag?(:local) %}
judge.as(LocalJudge).print
{% end %}
end
class 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)
end
def solve
1000.times do
ss = @judge.input
if !ss
debug("score:#{@exp}")
return
end
W.times do |x|
@es[x].rotate!(1)
@es[x][H - 1] = nil
end
ss.each do |s|
@es[s.x][H - 1] = Enemy.new(s.h, s.p)
@spawn_cnt[s.x] += 1
end
move = 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 -= @atk
if e.h <= 0
@exp += e.p
@atk = 1 + @exp // 100
@es[@px][y] = nil
end
break
end
end
end
@judge.output(move)
@turn += 1
end
debug("score:#{@exp}")
end
def spawn_cnt_bonus(x)
p = (@spawn_cnt[x] + 4) / (@turn + 100)
return p * 1
end
def select_move
debug("x:#{@px}")
best_v = 0.0
best_move = 0
1.upto(H - 1) do |ey|
if e = @es[@px][ey]
need = (e.h + @atk - 1) // @atk
if need <= ey - 0
eff = e.p / (0 + need + 1)
eff += spawn_cnt_bonus(@px)
if eff > best_v
best_v = eff
best_move = 0
debug("best_v:#{eff} #{@px} 0 0")
end
end
break
end
end
{-1, 1}.each do |move|
nx = mv(@px, move)
next if @es[nx][0] || @es[nx][1] && @es[nx][1].not_nil!.h > @atk
ny = 0
while nx != @px && ny < H - 3
(ny + 1).upto(H - 1) do |ey|
if e = @es[nx][ey]
need = (e.h + @atk - 1) // @atk
if need <= ey - ny
eff = e.p / (ny + need + 1)
eff += spawn_cnt_bonus(nx)
if eff > best_v
best_v = eff
best_move = move
debug("best_v:#{eff} #{nx} #{ny} #{move}")
end
end
break
end
end
ny += 1
if @es[nx][ny]
break
end
nnx = mv(nx, move)
next if @es[nnx][ny] || @es[nnx][ny + 1] && @es[nnx][ny + 1].not_nil!.h > @atk
nx = nnx
end
end
return best_move
end
def mv(x, d)
x += d
if x == -1
return W - 1
elsif x == W
return 0
else
return x
end
end
end
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0