結果
| 問題 |
No.5007 Steiner Space Travel
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-10-06 15:50:44 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 603 ms / 1,000 ms |
| コード長 | 3,383 bytes |
| コンパイル時間 | 233 ms |
| 実行使用メモリ | 85,604 KB |
| スコア | 7,314,610 |
| 最終ジャッジ日時 | 2022-10-06 15:51:06 |
| 合計ジャッジ時間 | 20,510 ms |
|
ジャッジサーバーID (参考情報) |
judge16 / judge13 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 30 |
ソースコード
import itertools
import random
import time
start = time.time()
N, M = map(int, input().split())
AB = [list(map(int, input().split())) for _ in range(N)]
class KMeans:
def __init__(self, n_clusters, max_iter = 10, random_seed = 0):
self.n_clusters = n_clusters
self.max_iter = max_iter
def fit(self, X):
self.labels_ = []
now = 0
while len(self.labels_) < len(X):
self.labels_.append(now)
now += 1
now %= self.n_clusters
random.shuffle(self.labels_)
labels_prev = [0]*len(X)
count = 0
self.cluster_centers_ = [(0, 0)] * self.n_clusters
while (not (self.labels_ == labels_prev) and count < self.max_iter):
syuukei = [[] for _ in range(self.n_clusters)]
for i in range(len(X)):
syuukei[self.labels_[i]].append(X[i])
for i,l in enumerate(syuukei):
if l:
x, y = sum(x for x,y in l)//len(l), sum(y for x,y in l)//len(l)
else:
x, y = random.randint(0, 1000), random.randint(0, 1000)
self.cluster_centers_[i] = (x, y)
labels_prev = self.labels_[:]
for i in range(len(X)):
dist = 10**18
for j in range(self.n_clusters):
tmp = (X[i][0] - self.cluster_centers_[j][0])**2 + (X[i][1] - self.cluster_centers_[j][1])**2
if tmp < dist:
dist = tmp
self.labels_[i] = j
count += 1
def main():
model = KMeans(8)
model.fit(AB)
labels = model.labels_
centers = model.cluster_centers_
def dist(a, b):
return (a[0] - b[0])**2 + (a[1] - b[1])**2
def calc(ans):
score = 0
for i in range(len(ans)-1):
type_pre, indx_pre = ans[i]
type_now, indx_now = ans[i+1]
if type_pre == 1 and type_now == 1:
score += 25*dist(AB[indx_pre], AB[indx_now])
if type_pre == 1 and type_now == 2:
score += 5*dist(AB[indx_pre], centers[indx_now])
if type_pre == 2 and type_now == 1:
score += 5*dist(centers[indx_pre], AB[indx_now])
if type_pre == 2 and type_now == 2:
score += 1*dist(centers[indx_pre], centers[indx_now])
return score
ANS = []
L = [[] for _ in range(8)]
for i, cluster_number in enumerate(labels):
L[cluster_number].append(i)
def calc_p(p):
score = dist((AB[0]), centers[p[0]])
for i in range(len(centers)-1):
score += dist(centers[p[i]], centers[p[i+1]])
score += dist(centers[p[-1]], AB[0])
return score
vest_p = None
vest = 1<<30
for p in itertools.permutations(range(8)):
score = calc_p(p)
if score < vest:
vest = score
vest_p = p[:]
if time.time() - start > 0.9:
return 1<<30, -1, -1
ans = [(1, 0)]
for i in vest_p:
if i >= len(L): continue
ans.append((2, i))
lim = len(L[i])
j = 0
while j < lim:
d1 = 5 * dist(AB[L[i][j]], centers[i])
d2 = 1<<30
if j+1 < len(L[i]):
d2 = 25* dist(AB[L[i][j]], AB[L[i][j+1]])
if d2 < d1:
ans.append((1, L[i][j]))
else:
ans.append((1, L[i][j]))
ans.append((2, i))
j += 1
ans.append((1, 0))
score = calc(ans)
return score, ans, centers
ANS = []
CENTERS = []
vest = 1<<30
while time.time() - start < 0.5:
tmp, ans, centers = main()
if tmp < vest:
vest = tmp
ANS = ans[:]
CENTERS = centers
for c,d in CENTERS:
print(c, d)
print(len(ANS))
for a,b in ANS:
print(a, b+1)