提出 #72942201
ソースコード 拡げる
import sys
import time
import random
import math
from collections import deque
# --- チューニング設定 ---
TIME_LIMIT = 1.95
SA_TIME_LIMIT = 1.45 # 高速化したので時間をたっぷりとる
SA_DEPTH = 8 # ビット演算なら深さ8まで余裕でいける
BFS_LIMIT = 3500
def solve():
start_time = time.time()
# --- 1. 入力 ---
try:
line1 = sys.stdin.readline().split()
if not line1: return
N, M, K, T = map(int, line1)
adj = [[] for _ in range(N)]
degrees = [0] * N
for _ in range(M):
u, v = map(int, sys.stdin.readline().split())
adj[u].append(v)
adj[v].append(u)
degrees[u] += 1
degrees[v] += 1
for _ in range(N):
sys.stdin.readline()
except ValueError:
return
# --- 2. Safe Core (安全圏) ---
is_safe = [True] * N
curr_degrees = list(degrees)
queue = deque([i for i in range(N) if curr_degrees[i] == 1])
while queue:
u = queue.popleft()
is_safe[u] = False
for v in adj[u]:
if is_safe[v]:
curr_degrees[v] -= 1
if curr_degrees[v] == 1:
queue.append(v)
if sum(is_safe) == 0:
for i in range(N):
if degrees[i] >= 2: is_safe[i] = True
# --- 3. 高速化前処理: パスのビットマスク用リスト ---
# shop_paths[k] = [ (length, [node_indices...]), ... ]
shop_paths = [[] for _ in range(K)]
for start_node in range(K):
q = deque([(start_node, -1, [])])
cnt = 0
while q:
u, p, path = q.popleft()
if path:
# パス自体を保存
shop_paths[start_node].append((len(path), path))
if len(path) >= SA_DEPTH:
continue
for v in adj[u]:
if v == p: continue
if v < K: continue
if not is_safe[v]: continue
# 枝刈り: あまりに多すぎるとSAが遅くなるので制限
if cnt > 1200: break
q.append((v, u, path + [v]))
cnt += 1
# --- 4. 爆速焼きなまし (Bitwise SA) ---
current_colors = [0] * N
# 初期解: 半分くらいRにしておく
for i in range(K, N):
if random.random() < 0.3: current_colors[i] = 1
best_colors = list(current_colors)
# スコア計算: 文字列操作を排除し、ビット演算とタプルのみで行う
# seen = set( (length, bitmask_value) )
def calc_score_fast(colors):
total_score = 0
r_count = 0
# Rの数ペナルティ(工事コスト削減のため)
# しかしPythonのsumは遅いので、差分更新したいがここでは簡易的に
# K以降のsumをとる
# r_count = sum(colors[K:]) * 0.5 # 係数は調整
for i in range(K):
seen = set()
local_score = 0
for length, path in shop_paths[i]:
# ビットマスク生成
val = 0
for idx, node in enumerate(path):
if colors[node]:
val |= (1 << idx)
# (長さ, 値) がユニークなら加点
key = (length, val)
if key not in seen:
seen.add(key)
# 長さの2乗をスコアに (長い文字列を強力に推奨)
local_score += length * length
total_score += local_score
# Rが多いと少し減点(1個あたり0.1点減点など、コスト意識)
# total_score -= sum(colors) * 0.1
return total_score
current_score = calc_score_fast(current_colors)
best_score = current_score
T0 = 200.0
T1 = 1.0
temp = T0
sa_iter = 0
while True:
sa_iter += 1
if (sa_iter & 255) == 0:
now = time.time()
if now - start_time > SA_TIME_LIMIT:
break
progress = (now - start_time) / SA_TIME_LIMIT
temp = T0 + (T1 - T0) * progress
target = random.randint(K, N - 1)
if not is_safe[target]: continue
current_colors[target] ^= 1
new_score = calc_score_fast(current_colors)
delta = new_score - current_score
if delta >= 0:
current_score = new_score
if current_score > best_score:
best_score = current_score
best_colors = list(current_colors)
else:
try:
prob = math.exp(delta / temp)
except OverflowError:
prob = 0
if random.random() < prob:
current_score = new_score
else:
current_colors[target] ^= 1 # Revert
# --- 5. 実行パート (Real-Cost Greedy) ---
real_tree_flavors = [0] * N
delivered_strings = [set() for _ in range(K)]
current_pos = 0
prev_pos = -1
current_ice = ""
action_queue = deque()
for t_idx in range(T):
turns_left = T - t_idx
# 計画作成
if not action_queue:
# (pos, prev, current_string, path_history, flip_cost)
q = deque([(current_pos, prev_pos, current_ice, [], 0)])
visited = { (current_pos, current_ice) }
candidates = []
bfs_cnt = 0
while q:
u, p, s, path, flips = q.popleft()
bfs_cnt += 1
if bfs_cnt > BFS_LIMIT: break
# 距離 + 工事コスト が残りターンを超えたら無意味
current_total_cost = len(path) + flips
if current_total_cost > turns_left: continue
if len(path) > 16: continue # 遠すぎるのは見ない
# ショップ到達
if u < K:
if s != "" and s not in delivered_strings[u]:
# 評価関数
# Value: 長さの2.5乗(長いのが正義)
# Cost: 移動距離 + (工事回数 * 1.5)
# ※工事には1ターンかかるが、リスクもあるので少し重く見る
score = len(s) ** 2.5
cost = len(path) + (flips * 1.2) + 0.1
efficiency = score / cost
candidates.append((path, score, efficiency))
continue
# 移動先列挙
next_nodes = []
for v in adj[u]:
if v == p: continue
if is_safe[u] and not is_safe[v]: continue
next_nodes.append(v)
for v in next_nodes:
new_flips = flips
if v >= K:
# 理想の色にする必要があるか?
# 現在の色を取得
actual_color = real_tree_flavors[v]
# 理想の色 (best_colors) を使う前提でパスを組む
target_color = best_colors[v]
# もし「今の現実」と「理想」が違うなら、工事コスト+1
# そして、その場所で得られる色は「理想の色」になる
if actual_color != target_color:
new_flips += 1
flavor = 'R' if target_color == 1 else 'W'
next_s = s + flavor
else:
next_s = s
if len(next_s) <= 8: # 長さ8まで許容
if (v, next_s) not in visited:
visited.add((v, next_s))
q.append((v, u, next_s, path + [v], new_flips))
# ベストパス選択
if candidates:
# 常に「効率(コスパ)」最優先
candidates.sort(key=lambda x: -x[2])
best_path = candidates[0][0]
for node in best_path:
action_queue.append(node)
# 味変予約: 現実と理想が違うなら変える
if node >= K and real_tree_flavors[node] != best_colors[node]:
action_queue.append(-1)
else:
# ランダム移動 (Safe優先)
cands = [v for v in adj[current_pos] if v != prev_pos]
safe_cands = [v for v in cands if is_safe[v]]
if is_safe[current_pos] and safe_cands:
action_queue.append(random.choice(safe_cands))
elif cands:
action_queue.append(random.choice(cands))
else:
pass
# --- 実行 (Safety Guard) ---
final_action = -999
while action_queue:
cand = action_queue.popleft()
if cand == -1:
# 味変: 今の場所で、色が違うなら実行
if current_pos < K: continue
if real_tree_flavors[current_pos] == best_colors[current_pos]: continue
final_action = -1; break
else:
if cand == prev_pos or cand not in adj[current_pos]: continue
final_action = cand; break
if final_action == -999:
cands = [v for v in adj[current_pos] if v != prev_pos]
safe_cands = [v for v in cands if is_safe[v]]
if is_safe[current_pos] and safe_cands: final_action = safe_cands[0]
elif cands: final_action = cands[0]
else: break
print(final_action)
sys.stdout.flush()
if final_action == -1:
# 味を反転
real_tree_flavors[current_pos] ^= 1
else:
prev_pos = current_pos
current_pos = final_action
if current_pos >= K:
current_ice += ('R' if real_tree_flavors[current_pos] else 'W')
else:
if current_ice: delivered_strings[current_pos].add(current_ice)
current_ice = ""
if __name__ == "__main__":
solve()
提出情報
| 提出日時 | |
|---|---|
| 問題 | A - Ice Cream Collection |
| ユーザ | glaceon1020 |
| 言語 | Python (PyPy 3.11-v7.3.20) |
| 得点 | 86044 |
| コード長 | 11075 Byte |
| 結果 | AC |
| 実行時間 | 1846 ms |
| メモリ | 120168 KiB |
ジャッジ結果
| セット名 | test_ALL | ||
|---|---|---|---|
| 得点 / 配点 | 86044 / 1500000 | ||
| 結果 |
|
| セット名 | テストケース |
|---|---|
| test_ALL | test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt, test_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt |
| ケース名 | 結果 | 実行時間 | メモリ |
|---|---|---|---|
| test_0000.txt | AC | 1702 ms | 117892 KiB |
| test_0001.txt | AC | 1760 ms | 119732 KiB |
| test_0002.txt | AC | 1687 ms | 117816 KiB |
| test_0003.txt | AC | 1708 ms | 118892 KiB |
| test_0004.txt | AC | 1696 ms | 118480 KiB |
| test_0005.txt | AC | 1738 ms | 118600 KiB |
| test_0006.txt | AC | 1664 ms | 117032 KiB |
| test_0007.txt | AC | 1706 ms | 117960 KiB |
| test_0008.txt | AC | 1744 ms | 119176 KiB |
| test_0009.txt | AC | 1765 ms | 119616 KiB |
| test_0010.txt | AC | 1719 ms | 119028 KiB |
| test_0011.txt | AC | 1704 ms | 117936 KiB |
| test_0012.txt | AC | 1804 ms | 118460 KiB |
| test_0013.txt | AC | 1708 ms | 117684 KiB |
| test_0014.txt | AC | 1724 ms | 118256 KiB |
| test_0015.txt | AC | 1676 ms | 117940 KiB |
| test_0016.txt | AC | 1745 ms | 118736 KiB |
| test_0017.txt | AC | 1718 ms | 117916 KiB |
| test_0018.txt | AC | 1759 ms | 118912 KiB |
| test_0019.txt | AC | 1751 ms | 119376 KiB |
| test_0020.txt | AC | 1727 ms | 118436 KiB |
| test_0021.txt | AC | 1791 ms | 119912 KiB |
| test_0022.txt | AC | 1711 ms | 118560 KiB |
| test_0023.txt | AC | 1766 ms | 118764 KiB |
| test_0024.txt | AC | 1695 ms | 117500 KiB |
| test_0025.txt | AC | 1749 ms | 119920 KiB |
| test_0026.txt | AC | 1695 ms | 117884 KiB |
| test_0027.txt | AC | 1754 ms | 118636 KiB |
| test_0028.txt | AC | 1713 ms | 118556 KiB |
| test_0029.txt | AC | 1761 ms | 118692 KiB |
| test_0030.txt | AC | 1730 ms | 118480 KiB |
| test_0031.txt | AC | 1756 ms | 119516 KiB |
| test_0032.txt | AC | 1708 ms | 117840 KiB |
| test_0033.txt | AC | 1708 ms | 118468 KiB |
| test_0034.txt | AC | 1783 ms | 118992 KiB |
| test_0035.txt | AC | 1706 ms | 118496 KiB |
| test_0036.txt | AC | 1678 ms | 118052 KiB |
| test_0037.txt | AC | 1673 ms | 117612 KiB |
| test_0038.txt | AC | 1779 ms | 120168 KiB |
| test_0039.txt | AC | 1727 ms | 118776 KiB |
| test_0040.txt | AC | 1680 ms | 117272 KiB |
| test_0041.txt | AC | 1765 ms | 118668 KiB |
| test_0042.txt | AC | 1691 ms | 118660 KiB |
| test_0043.txt | AC | 1715 ms | 118516 KiB |
| test_0044.txt | AC | 1664 ms | 117264 KiB |
| test_0045.txt | AC | 1725 ms | 117868 KiB |
| test_0046.txt | AC | 1706 ms | 118400 KiB |
| test_0047.txt | AC | 1708 ms | 118116 KiB |
| test_0048.txt | AC | 1700 ms | 117960 KiB |
| test_0049.txt | AC | 1748 ms | 118872 KiB |
| test_0050.txt | AC | 1674 ms | 117764 KiB |
| test_0051.txt | AC | 1702 ms | 118320 KiB |
| test_0052.txt | AC | 1677 ms | 117568 KiB |
| test_0053.txt | AC | 1846 ms | 119956 KiB |
| test_0054.txt | AC | 1717 ms | 118456 KiB |
| test_0055.txt | AC | 1670 ms | 118132 KiB |
| test_0056.txt | AC | 1772 ms | 119384 KiB |
| test_0057.txt | AC | 1666 ms | 117812 KiB |
| test_0058.txt | AC | 1785 ms | 119076 KiB |
| test_0059.txt | AC | 1686 ms | 117116 KiB |
| test_0060.txt | AC | 1681 ms | 117188 KiB |
| test_0061.txt | AC | 1700 ms | 117668 KiB |
| test_0062.txt | AC | 1716 ms | 119648 KiB |
| test_0063.txt | AC | 1714 ms | 118880 KiB |
| test_0064.txt | AC | 1701 ms | 117684 KiB |
| test_0065.txt | AC | 1700 ms | 117940 KiB |
| test_0066.txt | AC | 1708 ms | 118492 KiB |
| test_0067.txt | AC | 1680 ms | 118496 KiB |
| test_0068.txt | AC | 1740 ms | 119148 KiB |
| test_0069.txt | AC | 1691 ms | 117936 KiB |
| test_0070.txt | AC | 1695 ms | 117852 KiB |
| test_0071.txt | AC | 1719 ms | 118340 KiB |
| test_0072.txt | AC | 1694 ms | 117420 KiB |
| test_0073.txt | AC | 1663 ms | 117672 KiB |
| test_0074.txt | AC | 1728 ms | 118644 KiB |
| test_0075.txt | AC | 1787 ms | 118244 KiB |
| test_0076.txt | AC | 1666 ms | 118032 KiB |
| test_0077.txt | AC | 1708 ms | 117672 KiB |
| test_0078.txt | AC | 1732 ms | 118512 KiB |
| test_0079.txt | AC | 1721 ms | 118388 KiB |
| test_0080.txt | AC | 1765 ms | 119144 KiB |
| test_0081.txt | AC | 1724 ms | 118564 KiB |
| test_0082.txt | AC | 1804 ms | 119104 KiB |
| test_0083.txt | AC | 1700 ms | 117864 KiB |
| test_0084.txt | AC | 1716 ms | 118348 KiB |
| test_0085.txt | AC | 1736 ms | 118484 KiB |
| test_0086.txt | AC | 1702 ms | 118468 KiB |
| test_0087.txt | AC | 1714 ms | 118376 KiB |
| test_0088.txt | AC | 1751 ms | 118692 KiB |
| test_0089.txt | AC | 1743 ms | 119020 KiB |
| test_0090.txt | AC | 1771 ms | 118844 KiB |
| test_0091.txt | AC | 1703 ms | 117716 KiB |
| test_0092.txt | AC | 1765 ms | 118896 KiB |
| test_0093.txt | AC | 1699 ms | 117848 KiB |
| test_0094.txt | AC | 1696 ms | 118704 KiB |
| test_0095.txt | AC | 1734 ms | 119000 KiB |
| test_0096.txt | AC | 1686 ms | 117992 KiB |
| test_0097.txt | AC | 1730 ms | 118408 KiB |
| test_0098.txt | AC | 1688 ms | 117676 KiB |
| test_0099.txt | AC | 1679 ms | 118316 KiB |
| test_0100.txt | AC | 1685 ms | 117528 KiB |
| test_0101.txt | AC | 1738 ms | 118948 KiB |
| test_0102.txt | AC | 1702 ms | 118088 KiB |
| test_0103.txt | AC | 1720 ms | 118972 KiB |
| test_0104.txt | AC | 1714 ms | 118272 KiB |
| test_0105.txt | AC | 1756 ms | 118756 KiB |
| test_0106.txt | AC | 1739 ms | 118788 KiB |
| test_0107.txt | AC | 1805 ms | 119584 KiB |
| test_0108.txt | AC | 1725 ms | 118464 KiB |
| test_0109.txt | AC | 1694 ms | 118100 KiB |
| test_0110.txt | AC | 1723 ms | 118464 KiB |
| test_0111.txt | AC | 1731 ms | 119248 KiB |
| test_0112.txt | AC | 1706 ms | 117988 KiB |
| test_0113.txt | AC | 1709 ms | 118916 KiB |
| test_0114.txt | AC | 1797 ms | 118824 KiB |
| test_0115.txt | AC | 1674 ms | 117548 KiB |
| test_0116.txt | AC | 1712 ms | 118516 KiB |
| test_0117.txt | AC | 1753 ms | 118892 KiB |
| test_0118.txt | AC | 1704 ms | 118004 KiB |
| test_0119.txt | AC | 1728 ms | 118028 KiB |
| test_0120.txt | AC | 1782 ms | 119024 KiB |
| test_0121.txt | AC | 1727 ms | 119496 KiB |
| test_0122.txt | AC | 1747 ms | 119020 KiB |
| test_0123.txt | AC | 1675 ms | 118388 KiB |
| test_0124.txt | AC | 1800 ms | 119396 KiB |
| test_0125.txt | AC | 1698 ms | 119556 KiB |
| test_0126.txt | AC | 1712 ms | 118888 KiB |
| test_0127.txt | AC | 1732 ms | 117812 KiB |
| test_0128.txt | AC | 1696 ms | 117332 KiB |
| test_0129.txt | AC | 1691 ms | 117988 KiB |
| test_0130.txt | AC | 1754 ms | 119076 KiB |
| test_0131.txt | AC | 1687 ms | 118208 KiB |
| test_0132.txt | AC | 1729 ms | 117640 KiB |
| test_0133.txt | AC | 1728 ms | 118356 KiB |
| test_0134.txt | AC | 1726 ms | 118384 KiB |
| test_0135.txt | AC | 1757 ms | 119408 KiB |
| test_0136.txt | AC | 1756 ms | 119708 KiB |
| test_0137.txt | AC | 1701 ms | 118048 KiB |
| test_0138.txt | AC | 1666 ms | 117976 KiB |
| test_0139.txt | AC | 1718 ms | 118604 KiB |
| test_0140.txt | AC | 1785 ms | 118712 KiB |
| test_0141.txt | AC | 1738 ms | 118644 KiB |
| test_0142.txt | AC | 1714 ms | 118144 KiB |
| test_0143.txt | AC | 1736 ms | 119324 KiB |
| test_0144.txt | AC | 1712 ms | 118576 KiB |
| test_0145.txt | AC | 1768 ms | 118868 KiB |
| test_0146.txt | AC | 1658 ms | 117748 KiB |
| test_0147.txt | AC | 1697 ms | 117800 KiB |
| test_0148.txt | AC | 1730 ms | 118736 KiB |
| test_0149.txt | AC | 1794 ms | 118988 KiB |