結果
| 問題 |
No.5008 [Cherry Alpha] Discrete Pendulum with Air Resistance
|
| コンテスト | |
| ユーザー |
👑 Kazun
|
| 提出日時 | 2022-08-01 19:08:49 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 3,657 bytes |
| コンパイル時間 | 249 ms |
| 実行使用メモリ | 88,548 KB |
| スコア | 0 |
| 最終ジャッジ日時 | 2022-10-14 21:10:11 |
| 合計ジャッジ時間 | 18,170 ms |
|
ジャッジサーバーID (参考情報) |
judge14 / judge12 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | RE * 50 |
ソースコード
"""
作戦 0: 等差数列で写真を取る
作戦 1: 上位 L 枚を採用
作戦 2: 山登り
作戦 3: アニーリング
作戦 4: 初期解を頑張る.
作戦 5: 作戦 4 の下でアニーリング
"""
#==================================================
# 関数部
def debug(*message):
print(*message,file=sys.stderr)
def General_Binary_Increase_Search_Integer(L, R, cond, default=None):
""" 条件式が単調増加であるとき, 整数上で二部探索を行う.
L: 解の下限
R: 解の上限
cond: 条件(1変数関数, 広義単調増加を満たす)
default: Lで条件を満たさないときの返り値
"""
if not(cond(R)):
return default
if cond(L):
return L
R+=1
while R-L>1:
C=L+(R-L)//2
if cond(C):
R=C
else:
L=C
return R
def move(start,direction,time):
return start+direction*time
def position(i,T):
if T<B[i]:
return T
T-=B[i]
if T<F[i]:
check=lambda p:T<2*p*B[i]-p*p*E[i]
p=General_Binary_Increase_Search_Integer(1,H[i],check,None)
direction=pow(-1,p)
start=pow(-1,p-1)*(B[i]-(p-1)*E[i])
return move(start,direction,T-(2*(p-1)*B[i]-pow(p-1,2)*E[i]))
T-=F[i]
if T<(B[i]-H[i]*E[i])+M[i]:
direction=pow(-1,H[i]+1)
start=pow(-1,H[i])*(B[i]-H[i]*E[i])
return move(start,direction,T)
if M[i]>0:
T-=(B[i]-H[i]*E[i])+M[i]
q,r=divmod(T,2*M[i])
direction=pow(-1,H[i]+2+q)
start=pow(-1,H[i]+1+q)*M[i]
return move(start,direction,r)
else:
return 0
def PROBABILITY(delta,temp):
if delta>=0:
return 1
else:
return exp(delta/temp)
def picture(t):
X=[position(i,t) for i in range(N)]
score=0
for i in range(N):
for j in range(i+1,N):
score+=abs(X[i]-X[j])/(B[i]+B[j])
score*=pow(10,9)*(2/(N*(N-1)))
return round(score)
#==================================================
# インポート
from operator import itemgetter
from time import *
from heapq import *
from random import *
from math import *
import sys
#==================================================
# 入力
N,L,Delta=map(int,input().split())
B=[0]*N; M=[0]*N; E=[0]*N
for i in range(N):
B[i],M[i],E[i]=map(int,input().split())
#==================================================
H=[0]*N; F=[0]*N
for i in range(N):
H[i]=(B[i]-M[i])//E[i]
F[i]=2*B[i]*H[i]-E[i]*H[i]*H[i]
#==================================================
BEGIN_TIME=time()
FIRST_PHASE=0.300
SECOND_PHASE=1.550
TEMPERATURE=5
ALPHA=0.999
#==================================================
X=[]
t=0
while time()-BEGIN_TIME<FIRST_PHASE:
arg_t=-1
max_score=-1
for u in range(t+Delta,t+Delta+5):
score=picture(u)
if score>max_score:
max_score=score
arg_t=u
t=arg_t
X.append((t,max_score))
X.sort(key=itemgetter(1),reverse=True)
X=X[:L]
X.sort(key=itemgetter(0))
S=[s for _,s in X[:L]]; S=[0]+S+[0]
T=[t for t,_ in X[:L]]; T=[0]+T+[T[-1]+3*Delta]
BEGIN_TIME=time()
while time()-BEGIN_TIME<SECOND_PHASE:
j=randint(1,N)
if T[j-1]+Delta>T[j+1]-Delta:
continue
u=randint(T[j-1]+Delta, T[j+1]-Delta)
score=picture(u)
if random()<PROBABILITY(score-S[j],TEMPERATURE):
T[j]=u
S[j]=score
TEMPERATURE*=ALPHA
#==================================================
T=T[1:L+1]
print(len(T))
print(*T)
Kazun