結果
問題 | No.5017 Tool-assisted Shooting |
ユーザー | poka |
提出日時 | 2023-07-16 16:47:02 |
言語 | Julia (1.10.2) |
結果 |
AC
|
実行時間 | 1,491 ms / 2,000 ms |
コード長 | 7,722 bytes |
コンパイル時間 | 173 ms |
コンパイル使用メモリ | 7,068 KB |
実行使用メモリ | 324,004 KB |
スコア | 1,749,086 |
平均クエリ数 | 3191.00 |
最終ジャッジ日時 | 2024-04-09 14:21:53 |
合計ジャッジ時間 | 136,068 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,329 ms
317,344 KB |
testcase_01 | AC | 1,491 ms
322,684 KB |
testcase_02 | AC | 1,391 ms
314,532 KB |
testcase_03 | AC | 954 ms
307,444 KB |
testcase_04 | AC | 1,454 ms
322,480 KB |
testcase_05 | AC | 1,295 ms
315,948 KB |
testcase_06 | AC | 942 ms
310,104 KB |
testcase_07 | AC | 1,343 ms
321,932 KB |
testcase_08 | AC | 1,459 ms
322,484 KB |
testcase_09 | AC | 1,103 ms
315,272 KB |
testcase_10 | AC | 1,325 ms
321,076 KB |
testcase_11 | AC | 961 ms
310,972 KB |
testcase_12 | AC | 1,114 ms
312,328 KB |
testcase_13 | AC | 1,165 ms
314,228 KB |
testcase_14 | AC | 943 ms
310,356 KB |
testcase_15 | AC | 1,366 ms
323,308 KB |
testcase_16 | AC | 1,269 ms
312,804 KB |
testcase_17 | AC | 1,398 ms
320,512 KB |
testcase_18 | AC | 1,258 ms
312,516 KB |
testcase_19 | AC | 1,471 ms
321,180 KB |
testcase_20 | AC | 1,464 ms
321,804 KB |
testcase_21 | AC | 1,193 ms
314,448 KB |
testcase_22 | AC | 1,444 ms
322,068 KB |
testcase_23 | AC | 1,283 ms
315,328 KB |
testcase_24 | AC | 1,469 ms
323,076 KB |
testcase_25 | AC | 1,118 ms
315,364 KB |
testcase_26 | AC | 1,253 ms
312,204 KB |
testcase_27 | AC | 949 ms
312,296 KB |
testcase_28 | AC | 1,476 ms
322,816 KB |
testcase_29 | AC | 1,373 ms
322,788 KB |
testcase_30 | AC | 1,456 ms
322,896 KB |
testcase_31 | AC | 1,104 ms
314,660 KB |
testcase_32 | AC | 1,188 ms
313,892 KB |
testcase_33 | AC | 1,229 ms
314,616 KB |
testcase_34 | AC | 1,454 ms
322,920 KB |
testcase_35 | AC | 1,460 ms
320,908 KB |
testcase_36 | AC | 1,132 ms
314,988 KB |
testcase_37 | AC | 1,470 ms
320,836 KB |
testcase_38 | AC | 1,234 ms
313,080 KB |
testcase_39 | AC | 1,273 ms
312,348 KB |
testcase_40 | AC | 1,377 ms
323,604 KB |
testcase_41 | AC | 1,464 ms
323,580 KB |
testcase_42 | AC | 1,478 ms
322,480 KB |
testcase_43 | AC | 1,318 ms
316,984 KB |
testcase_44 | AC | 1,306 ms
319,168 KB |
testcase_45 | AC | 1,466 ms
322,300 KB |
testcase_46 | AC | 1,480 ms
320,472 KB |
testcase_47 | AC | 939 ms
305,492 KB |
testcase_48 | AC | 1,485 ms
322,720 KB |
testcase_49 | AC | 1,268 ms
314,616 KB |
testcase_50 | AC | 1,473 ms
322,148 KB |
testcase_51 | AC | 1,262 ms
315,068 KB |
testcase_52 | AC | 1,352 ms
320,952 KB |
testcase_53 | AC | 1,483 ms
322,356 KB |
testcase_54 | AC | 952 ms
310,624 KB |
testcase_55 | AC | 961 ms
311,216 KB |
testcase_56 | AC | 960 ms
309,848 KB |
testcase_57 | AC | 1,197 ms
312,036 KB |
testcase_58 | AC | 1,312 ms
315,672 KB |
testcase_59 | AC | 1,129 ms
314,160 KB |
testcase_60 | AC | 1,393 ms
321,092 KB |
testcase_61 | AC | 1,464 ms
321,444 KB |
testcase_62 | AC | 1,469 ms
323,788 KB |
testcase_63 | AC | 1,165 ms
314,180 KB |
testcase_64 | AC | 939 ms
308,296 KB |
testcase_65 | AC | 1,373 ms
321,420 KB |
testcase_66 | AC | 1,195 ms
314,816 KB |
testcase_67 | AC | 1,328 ms
323,428 KB |
testcase_68 | AC | 1,238 ms
314,684 KB |
testcase_69 | AC | 1,113 ms
315,536 KB |
testcase_70 | AC | 1,439 ms
320,408 KB |
testcase_71 | AC | 940 ms
310,484 KB |
testcase_72 | AC | 1,218 ms
315,520 KB |
testcase_73 | AC | 1,468 ms
320,432 KB |
testcase_74 | AC | 1,216 ms
314,136 KB |
testcase_75 | AC | 1,467 ms
320,576 KB |
testcase_76 | AC | 1,464 ms
322,808 KB |
testcase_77 | AC | 1,465 ms
324,004 KB |
testcase_78 | AC | 947 ms
311,624 KB |
testcase_79 | AC | 1,351 ms
323,032 KB |
testcase_80 | AC | 1,473 ms
320,664 KB |
testcase_81 | AC | 1,453 ms
322,504 KB |
testcase_82 | AC | 1,458 ms
321,112 KB |
testcase_83 | AC | 1,290 ms
314,916 KB |
testcase_84 | AC | 1,106 ms
315,404 KB |
testcase_85 | AC | 1,481 ms
322,216 KB |
testcase_86 | AC | 1,465 ms
322,880 KB |
testcase_87 | AC | 944 ms
307,912 KB |
testcase_88 | AC | 1,331 ms
321,660 KB |
testcase_89 | AC | 1,358 ms
320,568 KB |
testcase_90 | AC | 1,187 ms
314,748 KB |
testcase_91 | AC | 1,322 ms
323,128 KB |
testcase_92 | AC | 1,450 ms
322,860 KB |
testcase_93 | AC | 1,461 ms
323,392 KB |
testcase_94 | AC | 1,461 ms
321,128 KB |
testcase_95 | AC | 1,479 ms
321,780 KB |
testcase_96 | AC | 1,244 ms
313,120 KB |
testcase_97 | AC | 1,338 ms
320,780 KB |
testcase_98 | AC | 1,449 ms
323,580 KB |
testcase_99 | AC | 1,135 ms
316,256 KB |
ソースコード
module Problem const WIDTH = 25 const HEIGHT = 60 const MAX_TURN = 1000 const TIME_LIMIT = 1.65 const MIN_PERCENT = 1 const MAX_PERCENT = 8 const INF = 1 << 30 mutable struct Local row::Int inputs::Vector{String} end function Local() inputs = readlines() Local(2, inputs) end struct Server end readint(::Server) = parse(Int, readline()) readints(::Server) = parse.(Int, readline() |> split) function readint(l::Local) n = parse(Int, l.inputs[l.row]) l.row += 1 n end function readints(l::Local) nums = parse.(Int, split(l.inputs[l.row])) l.row += 1 nums end mutable struct Player x::Int level::Int breaking_power_total::Int score::Int end function Player() Player(12 + 1, 1, 0, 0) end mutable struct Enemy init_hp::Int now_hp::Int power::Int x::Int y::Int end function Enemy(init_hp, power, x0) Enemy(init_hp, init_hp, power, x0 + 1, HEIGHT) end mutable struct AppearanceCounter appear_count::Int no_appear_count::Int percent::Float64 end function AppearanceCounter() AppearanceCounter(0, 0, 5.0) end function percentage(counter::AppearanceCounter) p = counter.appear_count / (counter.appear_count + counter.no_appear_count) * 100 p = max(MIN_PERCENT, p) p = min(MAX_PERCENT, p) p end function preprocess!(enemies::Vector{Vector{Enemy}}, counters::Vector{AppearanceCounter}, new_enemies) counnts = [0 for _ in 1:WIDTH] for i in 1:WIDTH for j in eachindex(enemies[i]) enemies[i][j].y -= 1 end if !isempty(enemies[i]) && enemies[i][begin].y == 0 popfirst!(enemies[i]) end end for enemy in new_enemies push!(enemies[enemy.x], enemy) counnts[enemy.x] += 1 end for i in 1:WIDTH if counnts[i] > 0 counters[i].appear_count += 1 else counters[i].no_appear_count += 1 end end end function postprocess!(enemies::Vector{Vector{Enemy}}, player::Player) if !isempty(enemies[player.x]) enemies[player.x][begin].now_hp -= player.level if enemies[player.x][begin].now_hp <= 0 player.score += enemies[player.x][begin].init_hp player.breaking_power_total += enemies[player.x][begin].power player.level = 1 + player.breaking_power_total ÷ 100 popfirst!(enemies[player.x]) end end end function diff(a, b) (a - b)^2 end function update_percentages!(counters::Vector{AppearanceCounter}, probabilities, turn) t = turn / MAX_TURN for i in 1:WIDTH old_p = probabilities[i] expected_p = percentage(counters[i]) probabilities[i] = old_p probabilities[i] += old_p * (1 - t) + expected_p * t end end function enemy_evaluation1(enemy::Enemy, turn) t = turn / MAX_TURN value = enemy.power * (1 - t) + enemy.init_hp * t value end function approach_turn_simple(player::Player, enemies::Vector{Vector{Enemy}}, target_x) turn = 0 now = player.x enemies_ys = [Int[] for _ in 1:WIDTH] for i in 1:WIDTH for enemy in enemies[i] push!(enemies_ys[i], enemy.y) end end while now != target_x dirs = if mod(now - target_x, WIDTH) < mod(target_x - now, WIDTH) [-1, 0, 1] elseif mod(now - target_x, WIDTH) > mod(target_x - now, WIDTH) [1, 0, -1] else break end can_move = false for dir in dirs next = now + dir if next < 1 next += WIDTH elseif next > WIDTH next -= WIDTH end while !isempty(enemies_ys[next]) && enemies_ys[next][begin] < turn + 1 popfirst!(enemies_ys[next]) end if isempty(enemies_ys[next]) now = next turn += 1 can_move = true break else enemy_y = enemies_ys[next][begin] if enemy_y != turn + 1 now = next turn += 1 can_move = true break end end end if !can_move return INF end end turn end function expected_turn_for_braking(player::Player, enemies::Vector{Vector{Enemy}}, target_x) turn = 0 approach_turn = approach_turn_simple(player, enemies, target_x) if approach_turn == INF return INF end turn = approach_turn # # 移動して攻撃も移動せず攻撃も使うターンは変わらない # if turn > 0 # turn -= 1 # end braking_turn = (enemies[target_x][begin].now_hp + (player.level - 1)) ÷ player.level turn += braking_turn turn -= 1 # yが以下の場合は壊せない経過ターン # よくわからないけどバグ対策で1引いた if turn >= enemies[target_x][begin].y - 1 turn = INF end turn end function main(env) player = Player() enemies = [Enemy[] for _ in 1:WIDTH] counters = [AppearanceCounter() for _ in 1:WIDTH] probabilities = [4.5 for _ in 1:WIDTH] for turn in 1:MAX_TURN new_enemies = input(env) preprocess!(enemies, counters, new_enemies) update_percentages!(counters, probabilities, turn) cand_enemies = Enemy[] for i in 1:WIDTH if !isempty(enemies[i]) push!(cand_enemies, enemies[i][begin]) end end target_x = -1 best_value = -1 target_enemy = Enemy(0, 0, 0) for enemy in cand_enemies x = enemy.x earn_value = enemy_evaluation1(enemy, turn) use_turn = expected_turn_for_braking(player, enemies, x) value = earn_value / use_turn if best_value < value best_value = value target_x = x target_enemy = enemy end end dirs = if mod(player.x - target_x, WIDTH) < mod(target_x - player.x, WIDTH) ["L", "S", "R"] elseif mod(player.x - target_x, WIDTH) > mod(target_x - player.x, WIDTH) ["R", "S", "L"] else ["S", "L", "R"] end for dir in dirs now = player.x if dir == "L" now -= 1 if now < 1 now += WIDTH end elseif dir == "R" now += 1 if now > WIDTH now -= WIDTH end end if !isempty(enemies[now]) && enemies[now][begin].y == 1 continue else println(dir) player.x = now break end end println("# target_x: ", target_x) println("# best_value: ", best_value) println("# player: ", player.level) println("# enemy: ", target_enemy.now_hp) postprocess!(enemies, player) end end function input(env) n = readint(env) if n == -1 exit() end new_enemies = [Enemy(readints(env)...) for _ in 1:n] new_enemies end end #region run probblem if abspath(PROGRAM_FILE) == @__FILE__ env = Problem.Server() Problem.main(env) else tests_path = joinpath(@__DIR__, "in") file_name = "0000.txt" sample_file = joinpath(tests_path, file_name) out_path = joinpath(@__DIR__, "out") out_file = joinpath(out_path, file_name) redirect_stdio(stdin=sample_file, stdout=out_file) do env = Problem.Local() Problem.main(env) end end #endregion