結果
| 問題 |
No.5021 Addition Pyramid
|
| コンテスト | |
| ユーザー |
あじゃじゃ
|
| 提出日時 | 2025-02-25 21:32:24 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,647 ms / 2,000 ms |
| コード長 | 3,009 bytes |
| コンパイル時間 | 421 ms |
| コンパイル使用メモリ | 82,584 KB |
| 実行使用メモリ | 79,560 KB |
| スコア | 2,548,813 |
| 最終ジャッジ日時 | 2025-02-25 21:33:51 |
| 合計ジャッジ時間 | 86,678 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge6 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 50 |
ソースコード
from random import randint, choice
import math
import time
import random
start = time.time()
n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
mod = 10**8
def compute_A(candidate):
"""candidate から A を構成(リストの長さを固定して高速化)"""
A = [0] * (n + 1)
A[0] = candidate[0]
last_a = a[-1]
mod_val = mod
for i in range(n):
A[i + 1] = (last_a[i] - A[i] + candidate[i + 1]) % mod_val
return A
def score_from_candidate(candidate):
"""
compute_A(candidate) に基づいて誤差(gosa)を計算。
各段の誤差は abs(a[i][j] - computed_value) を mod を考慮して計算し、
その最大値を返します(誤差が小さいほど良い)。
"""
A = compute_A(candidate)
mod_val = mod
gosa = 0
d = A
# 下から上へ再帰的に計算(元のコードと同じ仕様)
for i in range(n - 2, 0, -1):
ai = a[i] # 行 i の値をローカル参照
ndp = [0] * i
for j in range(i):
s = d[j] + d[j - 1]
x = s % mod_val
ndp[j] = x
# 誤差を mod を考慮して計算
diff_val = x - ai[j]
if diff_val < 0:
diff_val = -diff_val
# mod 周りの距離に直す
diff_val = diff_val if diff_val < mod_val - diff_val else mod_val - diff_val
if diff_val > gosa:
gosa = diff_val
d = ndp
return gosa
# 初期候補解の生成(candidate[0]: 0~mod-1、candidate[1..n]: 計算で決定)
candidate = [randint(0, mod - 1)]
for i in range(n):
candidate.append((a[-1][i] - candidate[-1]) % mod)
current_score = score_from_candidate(candidate)
best_score = current_score
best_candidate = candidate[:]
# 焼きなましのパラメータ
T0 = 1e5
T_end = 1e-3
TIME_LIMIT = 1.6
while time.time() - start < TIME_LIMIT:
t = time.time() - start
T = T0 * ((T_end / T0) ** (t / TIME_LIMIT))
new_candidate = candidate[:] # candidate のコピー
idx = randint(0, n) # candidate のインデックスは 0~n
if idx == 0:
delta = randint(-1000, 1000)
new_candidate[0] = (new_candidate[0] + delta) % mod
else:
delta = choice([-1, 1])
new_candidate[idx] += delta
if new_candidate[idx] < 0:
new_candidate[idx] = 0
elif new_candidate[idx] > 10:
new_candidate[idx] = 10
new_score = score_from_candidate(new_candidate)
diff = new_score - current_score # 誤差最小化なので、diff が正なら悪化
# 改善(diff <= 0)の場合は必ず採用。劣化の場合は exp(-diff/T) の確率で採用。
if diff <= 0 or random.random() < math.exp(-diff / T):
candidate = new_candidate
current_score = new_score
if new_score < best_score:
best_score = new_score
best_candidate = new_candidate[:]
print(*compute_A(best_candidate))
あじゃじゃ