結果
問題 | No.5019 Hakai Project |
ユーザー |
![]() |
提出日時 | 2023-11-19 04:15:46 |
言語 | PyPy3 (7.3.15) |
結果 |
WA
|
実行時間 | - |
コード長 | 11,085 bytes |
コンパイル時間 | 342 ms |
コンパイル使用メモリ | 81,828 KB |
実行使用メモリ | 234,732 KB |
スコア | 0 |
最終ジャッジ日時 | 2023-11-19 04:16:52 |
合計ジャッジ時間 | 64,380 ms |
ジャッジサーバーID (参考情報) |
judge15 / judge14 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | WA * 50 |
ソースコード
def move(target_i, target_j):global costglobal ANSglobal current_i, current_jb = sum(B)while (current_i, current_j) != (target_i, target_j):if current_i < target_i:ANS.append((1, "D"))current_i += 1elif current_i > target_i:ANS.append((1, "U"))current_i -= 1elif current_j < target_j:ANS.append((1, "R"))current_j += 1elif current_j > target_j:ANS.append((1, "L"))current_j -= 1cost += (1 if A[current_i][current_j] in (".", "X") else 2) * (b + 1) ** 2print("Move to", (target_i, target_j), "cost =", cost)def buy(k):global costassert A[current_i][current_j] == "@"cost += price[k]B[k] += 1ANS.append((2, k + 1))if DEBUG:print("buy", k, "@", (current_i, current_j), "cost =", cost)def bomb_check(k, ii, jj):s = 0t = 0for i, j in Z[k][1]:ni = ii + inj = jj + jif 0 <= ni < N and 0 <= nj < N and A[ni][nj] != ".":if A[ni][nj] == "@":s += 1else:t += 1def bomb(k):assert B[k] > 0global shop_listB[k] -= 1ANS.append((3, k + 1))for i, j in Z[k][1]:ni = current_i + inj = current_j + jif 0 <= ni < N and 0 <= nj < N and A[ni][nj] != ".":if A[ni][nj] == "@":pass # shop_list.destroyedA[ni][nj] = "X"if DEBUG:print("bomb", k, "@", (current_i, current_j), "cost =", cost)def answer():print(len(ANS))for a, b in ANS:print(a, b)if DEBUG:print("cost =", cost)writetext_output(ANS)def disp():if DEBUG:print("")print("-" * 20)print("price =", price)print("inv =", price_inv)print("power =", power)building_cnt = sum(a.count("#") for a in A)shop_cnt = sum(a.count("@") for a in A)print("building cnt =", building_cnt)print("shop cnt =", shop_cnt)print("shop_list =", len(shop_list), shop_list)print("cost =", cost)print("score =", 1 if building_cnt else 10 ** 12 // (10 ** 4 + cost))print("A =")for a in A:print("".join(a))print("-" * 20)print("")try:LOCALexcept NameError:LOCAL = 0if LOCAL:DEBUG = 1# N, M, A, Z = random_testcase()print("Seed ?")I = input()N, M, A, Z = preset_testcase(int(I))else:DEBUG = 0N, M = map(int, input().split())A = []for _ in range(N):A.append([a for a in input()])Z = []for _ in range(M):C, L = map(int, input().split())pos = []for _ in range(L):a, b = map(int, input().split())pos.append((a, b))Z.append((C, pos))AA = [a[:] for a in A]cover_count_stay = [[-1 if aa == "." else 0 for aa in a] for a in A]if DEBUG:writetext_input(N, M, A, Z)price = []price_inv = []power = []position = []position_matrix = []B = [0] * Mcost = 0current_i = 0current_j = 0ANS = []if DEBUG:print("N =", N)print("M =", M)shop_list = []for i, a in enumerate(A):for j, aa in enumerate(a):if aa == "@":shop_list.append((i, j))shop_list_destroyed = [0] * len(shop_list)disp()for C, pos in Z:if DEBUG:print("C, cnt =", C, len(pos), "{:.4f}".format(len(pos) / C))print("pos =", pos)price.append(C)price_inv.append(10 ** 6 // C)power.append(len(pos))position.append(pos)if 0:print("")print("C =", C)print("cnt =", len(pos))z = [[0] * 41 for _ in range(41)]for i, j in pos:z[i][j] = 1position_matrix.append(z)if 0:print("pos =")for zz in z:print("".join(zz))def best_shop(i, j):best_i = -1best_j = -1best = 1000for ti, tj in shop_list:d = abs(ti - i) + abs(tj - j)if 0:d += (max(10 - ti, 0) + max(ti - 39, 0) + max(10 - tj, 0) + max(tj - 39, 0)) * 5if 21 <= ti < 29:d += 15if 21 <= tj < 29:d += 15if d < best:best = dbest_i = tibest_j = tjreturn best_i, best_jdef calc_favorite_shops():L = []# for ti, tj in ((9, 9), (9, 40), (40, 40), (40, 9)):for ti, tj in ((9, 9), (9, 24), (9, 40), (24, 40), (40, 40), (40, 24), (40, 9)):best = 10 ** 10best_k = -1for k, (i, j) in enumerate(shop_list):d = (ti - i) ** 2 + (tj - j) ** 2if d < best:best = dbest_k = kif best_k not in L:L.append(best_k)return Ldef calc_weight(shops):W = [[1.0] * N for _ in range(N)]for i in range(N):for j in range(N):for k in shops:si, sj = shop_list[k]d = max(abs(i - si), abs(j - sj))if d <= 20:for ss in (0.2, 0.6, 1.0):w = 1 / (1 + d * ss)W[i][j] *= (1 - w)for i in range(N):for j in range(N):W[i][j] = int(10 ** 4 * W[i][j]) + 1return Wdef find_best_cand():best = 0best_cand = Nonefor b, i, j, v in candidates_stay:k = favorite_shops[v]ev = 0si, sj = shop_list[k]for bi, bj in position[b]:ni = si + binj = sj + bjif 0 <= ni < N and 0 <= nj < N:# if AA[ni][nj] != ".":if cover_count_stay[ni][nj] == 0:ev += weight[ni][nj]ev *= price_inv[b]if ev > best:best = evbest_cand = (b, i, j, v)if DEBUG:if best_cand is not None:print("Best Cand Stay =", (b, i, j, v), int(ev / 10 ** 6 + 0.5))return best_cand# 基地とする店(お気に入りショップ)を選ぶfavorite_shops = calc_favorite_shops()if DEBUG:print("position =")for b, _pos in enumerate(position):print(b, _pos)print("favorite_shops =", favorite_shops)weight = calc_weight(favorite_shops)if DEBUG:print("weight =")for w in weight:print(w)favorite_shops_flg = [[-1] * N for _ in range(N)]for v, k in enumerate(favorite_shops):si, sj = shop_list[k]favorite_shops_flg[si][sj] = v# 基地からの攻撃候補candidates_stay = []for v, k in enumerate(favorite_shops):si, sj = shop_list[k]for b in range(M):for bi, bj in position[b]:ni = si + binj = sj + bjif (bi or bj) and 0 <= ni < N and 0 <= nj < N and favorite_shops_flg[ni][nj] > v:breakelse:candidates_stay.append((b, si, sj, v))strategy_stay = [[] for _ in range(len(favorite_shops))]for _ in range(10):b, i, j, v = find_best_cand()k = favorite_shops[v]strategy_stay[v].append((b, i, j))si, sj = shop_list[k]for bi, bj in position[b]:ni = si + binj = sj + bjif 0 <= ni < N and 0 <= nj < N:# if AA[ni][nj] != ".":# AA[ni][nj] = "."if cover_count_stay[ni][nj] >= 0:cover_count_stay[ni][nj] += 1if DEBUG:print("candidates_stay =", candidates_stay)print("strategy_stay =")for v in range(len(strategy_stay)):print(v, strategy_stay[v])cover_count_away = [[0 if aa == 0 else -1 for aa in a] for a in cover_count_stay]candidates_away = []candidates_efficiency = []candidates_matrix = [[[] for _ in range(N)] for _ in range(N)]for i in range(N):for j in range(N):for b in range(M):mav = -1for v, k in enumerate(favorite_shops):si, sj = shop_list[k]di, dj = si - i, sj - jif -20 <= di <= 20 and -20 <= dj <= 20 and position_matrix[b][di][dj]:mav = max(mav, v)best = 10 ** 9best_v = Nonefor v in range(mav + 1, len(favorite_shops)):k = favorite_shops[v]si, sj = shop_list[k]d = abs(i - si) + abs(j - sj)if d <= best:best = dbest_v = vif best_v is None:continuev = best_vk = favorite_shops[v]si, sj = shop_list[k]if v < len(favorite_shops):u = len(candidates_away)candidates_away.append((b, i, j, v))benefit = 0for bi, bj in position[b]:ni, nj = i + bi, j + bjif 0 <= ni < N and 0 <= nj < N:if cover_count_away[ni][nj] == 0:candidates_matrix[ni][nj].append(u)benefit += weight[ni][nj]moving_cost = (abs(i - si) + abs(j - sj)) * 5efficiency = 10 ** 6 // (price[b] + moving_cost) * benefitcandidates_efficiency.append(efficiency)if DEBUG:print("CHECKPOINT")def find_best_cand_away():best = 0best_cand = Nonefor efficiency, cand in zip(candidates_efficiency, candidates_away):if efficiency > best:best = efficiencybest_cand = candif DEBUG and best_cand is not None:print("Best Cand Away =", (b, i, j, v), "Efficiency =", "{:.3f}".format(best / 10 ** 6))return best_canddef update_candidates_away(b, i, j, v):for bi, bj in position[b]:ni, nj = i + bi, j + bjif 0 <= ni < N and 0 <= nj < N and cover_count_away[ni][nj] >= 0:cover_count_away[ni][nj] += 1if cover_count_away[ni][nj] == 1:for u in candidates_matrix[ni][nj]:_b, _i, _j, _v = candidates_away[u]k = favorite_shops[_v]si, sj = shop_list[k]moving_cost = (abs(_i - si) + abs(_j - sj)) * 5candidates_efficiency[u] -= 10 ** 6 // (price[_b] + moving_cost) * weight[ni][nj]strategy_away = [[] for _ in range(len(favorite_shops))]while 1:cand = find_best_cand_away()if cand is None:breakb, i, j, v = candupdate_candidates_away(b, i, j, v)strategy_away[v].append((b, i, j))if DEBUG:print("strategy_away")for v, s in enumerate(strategy_away):print(v, s)for v, k in enumerate(favorite_shops):si, sj = shop_list[k]for b, i, j in strategy_away[v]:move(si, sj)buy(b)move(i, j)bomb(b)move(si, sj)for b, i, j in strategy_stay[v]:move(i, j)buy(b)for b, i, j in strategy_stay[v]:bomb(b)answer()disp()