Codeforces Round #812 (Div. 2) D. Tournament Countdown(交互题)

记录一下第一次写交互题

 题目大意:一共有1<<n个人参加一场竞标赛,需要你通过比较两人的胜场来判断谁晋级,最终获得第一名

 最多1/3*2^(n+1)次询问,每次询问query(a,b),如果a胜场多返回1,如果b胜场多返回2,相同胜场返回0

 找到冠军后输出“! i”(i为冠军的编号)

思路:

  每次取四个人一组,因为如果这一组人进行了t轮比赛后,最终有一人胜出,那么他们的胜场将为

  [ t , t , t+1 , t+2 ],而且 t 和 t 不能出现在同一组,那么他们的胜场排列基本如下[ t , t+1       t , t+2 ]

  所以先对奇数进行查询(query(a[i],a[i+2])),如果相同(t==0),说明他们俩同时被淘汰,此时只用比较偶数组,谁多谁胜出

  否则如果不同,若返回1,说明a[i]为t+1或者t+2,这时只用比较a[i]与a[i+3]即可

  同理返回2

 

 
 1 # include<iostream>
 2 # include<bits/stdc++.h>
 3 using namespace std;
 4 # define int long long
 5  
 6 int ask(int a, int b) {
 7     cout << "? " << a << ' ' << b << endl;
 8     int t;
 9     cin >> t;
10     return t;
11 }
12 int tt;
13 signed main() {
14     ios::sync_with_stdio(0);
15     cin.tie(0);
16     cout.tie(0);
17     cin >> tt;
18     while (tt--) {
19         int n;
20         cin >> n;
21         vector<int> a;
22         n = 1 << n;
23         for (int i = 1; i <= n; ++i) {
24             a.push_back(i);
25         }
26         while (n >= 4) {
27             vector<int> b;
28             for (int i = 0; i < n; i += 4) {
29                 int t = ask(a[i], a[i + 2]);
30                 if (t == 0) {
31                     int t2 = ask(a[i + 1], a[i + 3]);
32                     if (t2 == 1) b.push_back(a[i + 1]);
33                     else b.push_back(a[i + 3]);
34                 } else if (t == 1) {
35                     int t2 = ask(a[i], a[i + 3]);
36                     if (t2 == 1) b.push_back(a[i]);
37                     else b.push_back(a[i + 3]);
38                 } else {
39                     int t2 = ask(a[i + 1], a[i + 2]);
40                     if (t2 == 1) b.push_back(a[i + 1]);
41                     else b.push_back(a[i + 2]);
42                 }
43             }
44             n /= 4;
45             a.swap(b);
46         }
47         if (a.size() == 2) {
48             int t = ask(a[0], a[1]);
49             if (t == 1) cout << '!' << ' ' << a[0] << endl;
50             else cout << '!' << ' ' << a[1] << endl;
51         } else cout << '!' << ' ' << a[0] << endl;
52  
53     }
54  
55  
56     return 0;
57 }

 

posted @ 2022-08-07 18:30  empty_y  阅读(44)  评论(0)    收藏  举报