結果

問題 No.3496 協力カード当て
コンテスト
ユーザー hiryuN
提出日時 2026-04-15 01:38:23
言語 PyPy3
(7.3.17)
コンパイル:
pypy3 -mpy_compile _filename_
実行:
pypy3 _filename_
結果
QLE  
実行時間 -
コード長 5,009 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 530 ms
コンパイル使用メモリ 85,492 KB
実行使用メモリ 75,164 KB
スコア 0
平均クエリ数 55.50
最終ジャッジ日時 2026-04-15 01:38:34
合計ジャッジ時間 3,716 ms
ジャッジサーバーID
(参考情報)
judge2_1 / judge3_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other QLE * 16
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

import sys

p, n, m = map(int, input().split())
my_cards = list(map(int, input().split()))
my_cards.sort()

# --- 1. 自分の手札から送信用キュー (QQ) を作成 ---
counts = {}
for x in my_cards:
    if x != 1:
        counts[x] = counts.get(x, 0) + 1

# 頻度順にソート (頻度が同じなら数字の昇順)
freq_list = []
for x, c in counts.items():
    freq_list.append((c, x))
freq_list.sort()

QQ = []
pre = 1
for c, x in freq_list:
    while pre < c:
        QQ.append(1)  # 頻度を上げるシグナル
        pre += 1
    QQ.append(x)

# すべて1だった場合など、送るものがないときの対策
if not QQ:
    last_q = m if m != 1 else 2
else:
    last_q = QQ[-1]

# --- 状態管理 ---
Ans = {}
q_idx = 0

partner_pre = 1
partner_cards_count = {}
prev_partner_q = -1

my_finished = False
partner_finished = False
fin = 0
already_guessed = False

# --- メインループ ---
while True:
    try:
        line = input().strip()
    except EOFError:
        break
        
    if line.startswith("END"):
        break

    if line == "TURN":
        # 自分がまだ手札情報を送信中の場合
        if not my_finished:
            if q_idx < len(QQ):
                ask_val = QQ[q_idx]
                q_idx += 1
                if q_idx == len(QQ):
                    my_finished = True
            else:
                ask_val = last_q
                my_finished = True
                
            print(f"ASK {ask_val}", flush=True)
            
            res_line = input().split()
            if res_line[0] == "COUNT":
                Ans[int(res_line[1])] = int(res_line[2])
                
        else:
            # 自分の送信が完了している場合
            if partner_finished:
                # 【双方完了】お互いに情報の伝達を終えたので回答フェーズへ
                if not already_guessed:
                    # 相手の手札を復元
                    partner_cards = []
                    for x, c in partner_cards_count.items():
                        partner_cards.extend([x] * c)
                    
                    # 相手の枚数が足りない分は「1」を持っていたとみなす
                    while len(partner_cards) < n:
                        partner_cards.append(1)
                        
                    # Cの手札を特定
                    C_cards = []
                    for i in range(1, m + 1):
                        my_c = my_cards.count(i)
                        partner_c = partner_cards.count(i)
                        # ASKしていない数字はAnsに無いので、最低限自分と相手の合計とする
                        total_c = Ans.get(i, my_c + partner_c) 
                        
                        c_count = total_c - my_c - partner_c
                        for _ in range(max(0, c_count)):
                            C_cards.append(i)
                            
                    C_cards.sort()
                    # 念のためN枚に切り詰める(不足時は1で埋める)
                    C_cards = C_cards[:n]
                    while len(C_cards) < n:
                        C_cards.append(1)
                    C_cards.sort()
                    
                    print("GUESS", *C_cards, flush=True)
                    already_guessed = True
                else:
                    # 既にGUESS済みなら終了を待つため適当にASK
                    print("ASK 1", flush=True)
                    
                res_line = input().split()
                if res_line[0] == "GUESSED":
                    if int(res_line[2]) == 1:
                        fin += 1
                elif res_line[0] == "COUNT":
                    Ans[int(res_line[1])] = int(res_line[2])
            else:
                # 自分は終わったが、相手がまだ終わっていない場合は「直前のクエリ」を送り続ける
                print(f"ASK {last_q}", flush=True)
                res_line = input().split()
                if res_line[0] == "COUNT":
                    Ans[int(res_line[1])] = int(res_line[2])

    elif line == "WAIT":
        res_line = input().split()
        if res_line[0] == "COUNT":
            q = int(res_line[1])
            Ans[q] = int(res_line[2])
            
            # 相手からの通信を受け取り、情報を更新する
            if not partner_finished:
                # 1以外の同じ値が連続して来たら、相手の送信は完了したとみなす
                if q == prev_partner_q and q != 1:
                    partner_finished = True
                else:
                    if q == 1:
                        partner_pre += 1
                    else:
                        partner_cards_count[q] = partner_pre
                    prev_partner_q = q
                    
        elif res_line[0] == "GUESSED":
            if int(res_line[2]) == 1:
                fin += 1
0