結果
| 問題 |
No.3001 ヘビ文字列
|
| ユーザー |
navel_tos
|
| 提出日時 | 2025-01-14 23:03:25 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,119 bytes |
| コンパイル時間 | 3,659 ms |
| コンパイル使用メモリ | 81,792 KB |
| 実行使用メモリ | 298,496 KB |
| 最終ジャッジ日時 | 2025-01-14 23:05:34 |
| 合計ジャッジ時間 | 89,835 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 79 TLE * 4 |
ソースコード
#yukicoder3001 ヘビ文字列
#愚直解 明らかにN - 1文字の変更でヘビ文字列になる点に注意
from itertools import product, combinations
def brute(T):
#1. Tを種類圧縮
N = len(T)
P = sorted(set(T))
Q = {Ti: i for i, Ti in enumerate(P)}
T = [ Q[Ti] for Ti in T ]
n = len(Q) #出現する種類数
#2. 気合いで全列挙 計算量はしらない
for k in range(N): #replace個数
for B in combinations( range(N), r = k ): #replace位置
for C in product( range(n), repeat = k ): #replace先
S = T[:]
for Bi, Ci in zip(B, C):
S[Bi] = Ci
for t in range(1, N): #S[t: t + N]とS[0: N]が一致するか判定
if all( S[i] == S[ (t + i) % N ] for i in range(N) ):
return k, S
#素因数分解
def factorial(N):
F = []
for n in range(2, N + 1):
if n > N:
break
if ( N % n == 0 ) and ( c := 0 ) == 0:
while N % n == 0 and ( c := c + 1 ):
N //= n
F.append((n, c))
if N > 1:
F.append((N, 1))
return F
#約数列挙
def divisor(N):
F = factorial(N)
D = [1]
for p, e in F:
nD = []
for n in D:
nD.append( n * ( q := 1 ) )
for _ in range(e):
nD.append( n * ( q := q * p ) )
D = nD
D.sort()
return D
#実験すると N = len(S) = 1441440 のとき、約数が最大で288個
#現在の解法は:
#for n in (Nの約数であって、Nでないもの):
# c = N
# for m in range(n):
# c -= ( S[m], S[m + n], S[m + 2n], ・・・ の文字種のうち最大のもの )
#cが最小となるnが理想のswap量。あとはよしなに
#for n: (Nの約数全体) とすると Dn = 288 よりループ回数がきつい
#でも普通にnは大きい方がよくない?Nの素因数の1種類だけをノックダウンすればよいのでは
def solve(T):
#1. Tを座標圧縮し、数列Sに変換する
C = sorted(set(T))
D = {Ti: i for i, Ti in enumerate(C)}
S = [D[Ti] for Ti in T]
n = len(D)
#2. swap量の候補を全探索し、replace数が最小となるswap量tを検索
rep = N = len(T)
rept = -1
A = [0] * n #種類数カウンター
F = factorial(N)
for Pi, Ei in F:
c = N
t = N // Pi
#tだけswapする
for m in range(t):
for i in range(m, N, t):
A[ S[i] ] += 1
c -= max(A)
for i in range(n):
A[i] = 0
if rep > c:
rep, rept = c, t
#3. reptだけswapすると決め打って最終構築
for m in range( rept ):
for i in range(m, N, rept):
A[ S[i] ] += 1
s = A.index( max(A) )
for i in range(m, N, rept):
S[i] = s
for i in range(n):
A[i] = 0
#4. Sを復元
for i in range(N):
S[i] = C[ S[i] ]
return ''.join(S)
#実行
print( solve(input()) )
navel_tos