結果
問題 |
No.5021 Addition Pyramid
|
ユーザー |
![]() |
提出日時 | 2025-02-25 22:27:18 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,882 ms / 2,000 ms |
コード長 | 3,295 bytes |
コンパイル時間 | 470 ms |
コンパイル使用メモリ | 82,364 KB |
実行使用メモリ | 80,860 KB |
スコア | 4,705,959 |
最終ジャッジ日時 | 2025-02-25 22:28:56 |
合計ジャッジ時間 | 97,192 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 50 |
ソースコード
import sys import time import math import random def solve(): input_data = sys.stdin.read().strip().split() MOD = 10**8 # 1. 入力読み取り N = int(input_data[0]) # N=50 a = [] idx = 1 for i in range(N): row = list(map(int, input_data[idx:idx + (i+1)])) a.append(row) idx += (i+1) # 2. 初期解 c: 最下段を a[N-1] と同じに c = a[N-1][:] # a[N-1] は長さN # ピラミッド構築 def build_pyramid(c_list): # b[i] は上から i段目(0-index)。b[0] が最上段、b[N-1] が最下段 b = [[0]*(i+1) for i in range(N)] b[N-1] = c_list[:] # コピー for i in reversed(range(N-1)): for j in range(i+1): b[i][j] = (b[i+1][j] + b[i+1][j+1]) % MOD return b # 最大サイクル距離(問題指定の誤差)を計算 def max_cycle_dist(a_pyr, b_pyr): diff_max = 0 for i in range(N): for j in range(i+1): d = abs(a_pyr[i][j] - b_pyr[i][j]) # mod 1e8 での距離 if d > MOD // 2: d = MOD - d if d > diff_max: diff_max = d return diff_max # コスト(= 最大誤差)を計算する関数 def calc_cost(c_list): b_pyramid = build_pyramid(c_list) return max_cycle_dist(a, b_pyramid) # 初期解のコスト current_cost = calc_cost(c) best_c = c[:] best_cost = current_cost # 焼きなまし用パラメータ T = 100.0 # 初期温度(調整パラメータ) COOL = 0.995 # 温度減衰率(調整パラメータ) start_time = time.time() # 3. 焼きなましループ while True: # 時間制限チェック if time.time() - start_time > 1.8: break # ランダムに 1箇所 選んで ±1 する (近傍操作) j = random.randint(0, N-1) old_val = c[j] # ±1 のどちらかをランダムに delta = 1 if (random.random() < 0.5) else -1 c[j] = (c[j] + delta) % MOD # 新コストを計算 new_cost = calc_cost(c) # 変化量 (SAでは"コストは小さい方が良い"ので old-new) diff = current_cost - new_cost if diff > 0: # 改善なら常に採用 current_cost = new_cost if new_cost < best_cost: best_cost = new_cost best_c = c[:] else: # 悪化する場合は確率的に採用 # (diff が負なので -diff は正数) p = math.exp(diff / T) # diff < 0 なので 0 < p < 1 if random.random() < p: # 採用 current_cost = new_cost if new_cost < best_cost: best_cost = new_cost best_c = c[:] else: # 棄却: 元に戻す c[j] = old_val # 温度を下げる T *= COOL # 4. 結果出力 (最良解) print(" ".join(map(str, best_c))) if __name__ == "__main__": sys.setrecursionlimit(10**7) solve()