結果
| 問題 |
No.5008 [Cherry Alpha] Discrete Pendulum with Air Resistance
|
| コンテスト | |
| ユーザー |
👑 Kazun
|
| 提出日時 | 2022-08-01 18:58:59 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 3,623 bytes |
| コンパイル時間 | 263 ms |
| 実行使用メモリ | 88,692 KB |
| スコア | 0 |
| 最終ジャッジ日時 | 2022-10-14 21:10:16 |
| 合計ジャッジ時間 | 17,982 ms |
|
ジャッジサーバーID (参考情報) |
judge13 / judge12 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | RE * 50 |
ソースコード
"""
作戦 0: 等差数列で写真を取る
作戦 1: 上位 L 枚を採用
作戦 2: 山登り
作戦 3: アニーリング
"""
#==================================================
# 関数部
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)
#==================================================
# インポート
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=1.300
SECOND_PHASE=0.550
TEMPERATURE=5
ALPHA=0.995
T_max=pow(10,9)
#==================================================
# Phase 1
Q=[]
t=100
m=0
while time()-BEGIN_TIME<FIRST_PHASE:
m+=1
X=[position(i,t) for i in range(N)]
s=0
for i in range(N):
for k in range(i+1,N):
s+=abs(X[i]-X[k])/(B[i]+B[k])
Q.append((s,t))
t+=Delta
if len(Q)>=2*L:
Q.sort(key=itemgetter(0),reverse=True)
Q=Q[:L]
debug("1st",m)
Q.sort(key=itemgetter(0),reverse=True)
Q=Q[:L]
Q.sort(key=itemgetter(1))
S=[0]*(N+2); T=[0]*(N+2)
for i in range(N):
S[i+1],T[i+1]=Q[i]
T[-1]=T_max+Delta
# Phase 2
T_ans=T.copy(); max_score=score=sum(S)
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)
X=[position(i,u) for i in range(N)]
ss=0
for i in range(N):
for k in range(i+1,N):
ss+=abs(X[i]-X[k])/(B[i]+B[k])
delta=ss-S[j]
if random()<PROBABILITY(delta,TEMPERATURE):
T[j]=u
S[j]=ss
score+=delta
if score>max_score:
max_score=score
T_ans=T.copy()
TEMPERATURE*=ALPHA
#==================================================
T=T_ans[1:L+1]
debug(TEMPERATURE)
print(len(T))
print(*sorted(T))
Kazun