Submission #46716313


Source Code Expand

import random
import math
from collections import defaultdict
import bisect
N, D, Q = map(int, input().split())
remainQ = Q

# 30≤N≤100

# なんとなくの重さの順序付けをして初期配置を決める処理 Nは最大100
# weights = [1,5,3,7,89,2,90] # 実際には見えない裏に持ってるお土産ごとの重さ
# N = len(weights)
# D = 3

def compare_single(g1, g2):
    # 1個ずつ比較
    global remainQ
    print(1, 1, g1, g2, flush=True)
    remainQ -= 1
    ret = input()
    # todo イコール対策
    if ret == "=":
        ret = "<"
    return ret

def compare_group(g1, g2, dict_idx):
    global remainQ
    print(len(dict_idx[g1]), len(dict_idx[g2]), *dict_idx[g1], *dict_idx[g2], flush=True)
    remainQ -= 1
    return input()

def create_tree(par:list, idxs:list)->int:
    """
    idxs親を求めるインデックス一覧
    root 新しくできたindex
    """
    # 親配列初期化
    for idx in idxs:
        par[idx]= -1
    left = idxs[0]
    for right in idxs[1:]:
        ret = compare_single(left, right)
        if ret == "<":
            par[left] = right
            left = right
        else:
            par[right] = left
    par[left] = -1
    return left
def get_nodes(par:list, root:int)->list:
    """
    rootに繋がってる要素一覧取得
    """
    indices = [index for index, item in enumerate(par) if item == root]
    return indices

def init_desc_groups(thr:int):
    """
    残り回数thrを切るまで単純比較して、ある程度傾斜をつけた初期配列を取得する
    """
    par = [-1]*N # 親配列
    nodes = list(range(N))#最初は全部親がわからない
    desc_list = []#暫定降順配列

    for _ in range(N):
        if len(nodes) == 1:
            root = nodes[0]
            par[root] = -1
        else:
            root = create_tree(par,nodes)
        desc_list.append(root)
        nodes = get_nodes(par, root)
        # print(root,par,nodes)
        if (Q - remainQ) >= thr:
            break
        if len(desc_list) == MAX_SELECT:
            break
    # print(root,par,desc_list)

    # 降順リストに入らなかったものを混ぜる
    unknown = list(range(N))
    for v in desc_list:
        unknown.remove(v)
    random.shuffle(unknown)
    omiyage = desc_list + unknown
    ans = [-1]*N
    tmp = (list(range(D)) + list(range(D-1,-1,-1)))*50#最低でも100にする
    tmp = tmp[:N]

    for i, idx in enumerate(omiyage):
        # ans[idx] = i%D
        ans[idx] = tmp[i]
    return ans

def init_swiss_groups(round:int):
    rank = [[0,i] for i in range(N)]# [-勝利数, 選手の番号]のリスト
    for _ in range(round):
        for i in range(N//2):
            p1 = rank[2*i][1]
            p2 = rank[2*i+1][1]
            ret = compare_single(p1, p2)
            if ret == "<":
                rank[2*i+1][0] -= 1            
            else:
                rank[2*i][0] -= 1
        # 奇数対策
        if N%2 == 1:
            rank[-1][0] -= 0.5
        rank.sort()

    omiyage = [i for _, i in rank]
    swiss_score = dict()
    for item in rank:
        swiss_score[item[1]] = item[0]
    ans = [-1]*N
    tmp = (list(range(D)) + list(range(D-1,-1,-1)))*50#最低でも100にする
    tmp = tmp[:N]

    for i, idx in enumerate(omiyage):
        # ans[idx] = i%D
        ans[idx] = tmp[i]
    return ans

def move_random_rollback(ans):
    dict_idx = defaultdict(list)
    for i, v in enumerate(ans):
        dict_idx[v].append(i)

    while remainQ:
        # どの集合を調整するか選ぶ
        g1, g2 = random.sample(range(D), 2) 
        # Interactive
        ret = compare_group(g1, g2, dict_idx)
        if ret == "=": continue
        # g1のほうが大きいようにする
        if ret == "<":
            g1, g2 = g2, g1
        # G1からG2に移動させる
        if len(dict_idx[g1]) == 1: continue
        while remainQ:
            item = random.choice(dict_idx[g1])
            dict_idx[g1].remove(item)
            dict_idx[g2].append(item)
            ret = compare_group(g1, g2, dict_idx)
            if ret == ">":
                ans[item] = g2 # 移動を確定させる
                if len(dict_idx[g1]) == 1:
                    break
            elif ret == "=":
                ans[item] = g2 # 移動を確定させる
                break
            else:
                if remainQ > yakinamashiT and random.randint(1,100) >= yakinamashiR: 
                    ans[item] = g2 # 移動を確定させる
                else:
                    dict_idx[g1].append(item)
                    dict_idx[g2].remove(item)
                break
    return ans

# 順番初期配列
# ans = [None]*N
# ans = [i%D for i in range(N)] # random split

# 降順初期配列
THR = Q//3 #残り回数thr回を割ったらやめる
MAX_SELECT = D*2 # 最大何個降順で引っ張る?
# ans = init_desc_groups(THR)

SWISS_THR = Q//4 #どれくらいスイスする?
n_round_swiss1 = math.ceil(math.log2(N))#スイスドローを何ラウンドすると1位が決まるか
l_swiss = [(N//2)*i for i in range(1000)] # nラウンド目まで終わったときの試合数
n_round_swiss2 = bisect.bisect_left(l_swiss,SWISS_THR) #THRまですると何ラウンド?
ans = init_swiss_groups(n_round_swiss2)


yakinamashiT = 200 # 残り回数なん回まで焼きなまし適用させるか
yakinamashiR = 100 # 焼きなましするときの、悪い交換を許容しない確率
ans = move_random_rollback(ans)
print(*ans)

Submission Info

Submission Time
Task A - Balancing by Balance
User te1229
Language Python (PyPy 3.10-v7.3.12)
Score 448424130
Code Size 5705 Byte
Status AC
Exec Time 153 ms
Memory 85772 KiB

Judge Result

Set Name test_ALL
Score / Max Score 448424130 / 100000000000
Status
AC × 100
Set Name Test Cases
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
Case Name Status Exec Time Memory
test_0000.txt AC 97 ms 84292 KiB
test_0001.txt AC 121 ms 84404 KiB
test_0002.txt AC 115 ms 84564 KiB
test_0003.txt AC 92 ms 84156 KiB
test_0004.txt AC 98 ms 84520 KiB
test_0005.txt AC 90 ms 84472 KiB
test_0006.txt AC 137 ms 85036 KiB
test_0007.txt AC 121 ms 84968 KiB
test_0008.txt AC 108 ms 84744 KiB
test_0009.txt AC 98 ms 84620 KiB
test_0010.txt AC 101 ms 84676 KiB
test_0011.txt AC 109 ms 84772 KiB
test_0012.txt AC 91 ms 84452 KiB
test_0013.txt AC 96 ms 84576 KiB
test_0014.txt AC 114 ms 84664 KiB
test_0015.txt AC 102 ms 84644 KiB
test_0016.txt AC 93 ms 84164 KiB
test_0017.txt AC 94 ms 84460 KiB
test_0018.txt AC 128 ms 85140 KiB
test_0019.txt AC 91 ms 84688 KiB
test_0020.txt AC 129 ms 84908 KiB
test_0021.txt AC 101 ms 84536 KiB
test_0022.txt AC 105 ms 84916 KiB
test_0023.txt AC 96 ms 84324 KiB
test_0024.txt AC 119 ms 84608 KiB
test_0025.txt AC 102 ms 84984 KiB
test_0026.txt AC 131 ms 85120 KiB
test_0027.txt AC 91 ms 84760 KiB
test_0028.txt AC 94 ms 84324 KiB
test_0029.txt AC 112 ms 84692 KiB
test_0030.txt AC 93 ms 84380 KiB
test_0031.txt AC 87 ms 84160 KiB
test_0032.txt AC 106 ms 84388 KiB
test_0033.txt AC 100 ms 84292 KiB
test_0034.txt AC 130 ms 85160 KiB
test_0035.txt AC 95 ms 84300 KiB
test_0036.txt AC 93 ms 84512 KiB
test_0037.txt AC 119 ms 84776 KiB
test_0038.txt AC 106 ms 84960 KiB
test_0039.txt AC 113 ms 84504 KiB
test_0040.txt AC 128 ms 85096 KiB
test_0041.txt AC 109 ms 84580 KiB
test_0042.txt AC 98 ms 84584 KiB
test_0043.txt AC 128 ms 85164 KiB
test_0044.txt AC 119 ms 84796 KiB
test_0045.txt AC 99 ms 84572 KiB
test_0046.txt AC 103 ms 84924 KiB
test_0047.txt AC 134 ms 84932 KiB
test_0048.txt AC 130 ms 85172 KiB
test_0049.txt AC 102 ms 84616 KiB
test_0050.txt AC 104 ms 84396 KiB
test_0051.txt AC 104 ms 84308 KiB
test_0052.txt AC 153 ms 85272 KiB
test_0053.txt AC 103 ms 84712 KiB
test_0054.txt AC 92 ms 84504 KiB
test_0055.txt AC 89 ms 84440 KiB
test_0056.txt AC 102 ms 84484 KiB
test_0057.txt AC 106 ms 85088 KiB
test_0058.txt AC 102 ms 84688 KiB
test_0059.txt AC 116 ms 84744 KiB
test_0060.txt AC 123 ms 84604 KiB
test_0061.txt AC 93 ms 84256 KiB
test_0062.txt AC 119 ms 84360 KiB
test_0063.txt AC 114 ms 84468 KiB
test_0064.txt AC 92 ms 84264 KiB
test_0065.txt AC 93 ms 84700 KiB
test_0066.txt AC 143 ms 85772 KiB
test_0067.txt AC 99 ms 84712 KiB
test_0068.txt AC 113 ms 84832 KiB
test_0069.txt AC 99 ms 84352 KiB
test_0070.txt AC 104 ms 84728 KiB
test_0071.txt AC 111 ms 84704 KiB
test_0072.txt AC 113 ms 84672 KiB
test_0073.txt AC 102 ms 84620 KiB
test_0074.txt AC 116 ms 85096 KiB
test_0075.txt AC 95 ms 84584 KiB
test_0076.txt AC 103 ms 84360 KiB
test_0077.txt AC 104 ms 84472 KiB
test_0078.txt AC 104 ms 84600 KiB
test_0079.txt AC 97 ms 84652 KiB
test_0080.txt AC 89 ms 83940 KiB
test_0081.txt AC 96 ms 84732 KiB
test_0082.txt AC 93 ms 84540 KiB
test_0083.txt AC 96 ms 84720 KiB
test_0084.txt AC 118 ms 84360 KiB
test_0085.txt AC 97 ms 84576 KiB
test_0086.txt AC 93 ms 84216 KiB
test_0087.txt AC 151 ms 85620 KiB
test_0088.txt AC 141 ms 85572 KiB
test_0089.txt AC 118 ms 84564 KiB
test_0090.txt AC 105 ms 84816 KiB
test_0091.txt AC 107 ms 84960 KiB
test_0092.txt AC 119 ms 85016 KiB
test_0093.txt AC 94 ms 84504 KiB
test_0094.txt AC 106 ms 84400 KiB
test_0095.txt AC 96 ms 84912 KiB
test_0096.txt AC 128 ms 85640 KiB
test_0097.txt AC 113 ms 84484 KiB
test_0098.txt AC 106 ms 84784 KiB
test_0099.txt AC 103 ms 84600 KiB