結果
| 問題 | No.3408 1215 Segments |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-12-09 15:37:59 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,919 ms / 2,500 ms |
| コード長 | 5,703 bytes |
| 記録 | |
| コンパイル時間 | 311 ms |
| コンパイル使用メモリ | 82,564 KB |
| 実行使用メモリ | 85,036 KB |
| 最終ジャッジ日時 | 2025-12-14 23:36:27 |
| 合計ジャッジ時間 | 28,329 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 46 |
ソースコード
import sys
# 再帰深度の上限を緩和(念のため)
sys.setrecursionlimit(5000)
def main():
# 高速I/O
input = sys.stdin.readline
try:
line = input().strip()
if not line:
return
n = int(line)
except ValueError:
return
s = str(n)
length_n = len(s)
# 計算用バッファ(0-9の個数)
counts = [0] * 10
# 答えを格納するコンテナ(リストにして参照で書き換え可能にする)
# Javaの static String minForLen に相当
best_ans = [None]
# -----------------------------------------------------
# 内部関数定義 (クロージャとして実装)
# -----------------------------------------------------
def solve_recursive(idx, tight, current_counts, target_str):
if idx == len(target_str):
return ""
start = int(target_str[idx]) if tight else 0
for d in range(start, 10):
if current_counts[d] > 0:
current_counts[d] -= 1
next_tight = tight and (d == start)
if not next_tight:
# 制約が外れた場合(targetより大きい桁を選んだ場合)
# 残りは辞書順最小(0から順に詰める)で作る
res = [str(d)]
for k in range(10):
if current_counts[k] > 0:
res.append(str(k) * current_counts[k])
current_counts[d] += 1 # backtrack
return "".join(res)
# 制約が続く場合
res = solve_recursive(idx + 1, next_tight, current_counts, target_str)
if res is not None:
current_counts[d] += 1 # backtrack
return str(d) + res
current_counts[d] += 1 # backtrack
return None
def find_smallest(current_counts, target_str):
total_digits = sum(current_counts)
if total_digits > len(target_str):
# 桁数がtargetより多い場合、最小の非ゼロ数字を先頭にして残りを昇順
for d in range(1, 10):
if current_counts[d] > 0:
current_counts[d] -= 1
res = [str(d)]
for k in range(10):
if current_counts[k] > 0:
res.append(str(k) * current_counts[k])
current_counts[d] += 1 # backtrack
return "".join(res)
return None
else:
# 桁数が同じ場合、target_str以上になる最小の並び替えを探す
return solve_recursive(0, True, current_counts, target_str)
def check_and_update(cnt, target_str, L):
# 高速な妥当性チェック
if (L + cnt[0] + cnt[6] + cnt[8]) % 2 != 0:
return
# Javaロジックのセグメント計算
s0 = cnt[0] + cnt[2] + cnt[3] + cnt[5] + cnt[6] + cnt[7] + cnt[8] + cnt[9]
s1 = cnt[0] + cnt[1] + cnt[2] + cnt[3] + cnt[4] + cnt[7] + cnt[8] + cnt[9]
s2 = L - cnt[2]
s3 = cnt[0] + cnt[2] + cnt[3] + cnt[5] + cnt[6] + cnt[8] + cnt[9]
s4 = cnt[0] + cnt[2] + cnt[6] + cnt[8]
s5 = cnt[0] + cnt[4] + cnt[5] + cnt[6] + cnt[8] + cnt[9]
s6 = cnt[2] + cnt[3] + cnt[4] + cnt[5] + cnt[6] + cnt[8] + cnt[9]
base = (s2 + s4) // 2
nine = s3 - base
one = base - s4
zero = (s1 - one) - base
seven = base - (s5 - zero + one)
six = (s0 - zero) - base
# 負の値チェック
if one < 0 or zero < 0 or seven < 0 or six < 0 or nine < 0: return
# 上限チェック
if one > cnt[1]: return
if zero > cnt[0]: return
if seven > cnt[7]: return
if six > cnt[6]: return
if nine > cnt[9]: return
# 整合性チェック
if s0 - zero - six != base: return
if s1 - one - zero != base: return
if s2 - one != base: return
if s3 - nine != base: return
if s4 + one != base: return
if s5 - zero + one + seven != base: return
if s6 + zero != base: return
# 有効なら最小値を構築
candidate = find_smallest(cnt, target_str)
if candidate is not None:
if best_ans[0] is None:
best_ans[0] = candidate
else:
# 辞書順比較 (長さ比較含む)
if len(candidate) < len(best_ans[0]):
best_ans[0] = candidate
elif len(candidate) == len(best_ans[0]) and candidate < best_ans[0]:
best_ans[0] = candidate
def dfs(digit, remaining, current_counts, target_str, L):
if digit == 9:
current_counts[9] = remaining
check_and_update(current_counts, target_str, L)
current_counts[9] = 0 # backtrack
return
for i in range(remaining + 1):
current_counts[digit] = i
dfs(digit + 1, remaining - i, current_counts, target_str, L)
current_counts[digit] = 0 # backtrack
# -----------------------------------------------------
# メインループ
# -----------------------------------------------------
for l in range(length_n, 21):
best_ans[0] = None
dfs(0, l, counts, s, l)
if best_ans[0] is not None:
print(best_ans[0])
break
if __name__ == '__main__':
main()