Codeforces Round #812 (Div. 2) D
链接
https://codeforces.com/contest/1713/problem/D
交互题,有 $ 2^n $ 名玩家进行单淘汰赛制比赛,需要你在不多于 $\lceil \frac{2}{3} * 2^n \rceil $ 次询问后找到最后获胜的人
每次询问 “? a b” , 回答一个整数 ,如果回答1表示a的获胜次数大于b,2表示b的获胜次数大于a,0表示两人获胜次数相同
思路
提示:
\(\frac{2}{3} = \frac{4}{3} * \frac{1}{2} = \frac{\frac{1}{2}}{\frac{3}{4}}\) 形式有点类似公比为 \(\frac{1}{4}\) 的等比数列求和公式
直接构造也没问题
直接构造:
结论:4个数为1组进行询问,可以只问2次就知道这一组中的胜者
因为每次都是1和2比,3和4比...(以此类推),所以按顺序分组
上代码:
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pb push_back
using namespace std;
int n,k;
int a[4];
deque<int> v, tem;
int query(){
cout << "? " << a[0] << " " << a[2] <<endl; fflush(stdout);
cin >> k;
if (k == 0) {
cout << "? " << a[1] << " " << a[3] <<endl; fflush(stdout);
cin >> k;
if (k == 1) return a[1];
else return a[3];
}
if (k == 1) {
cout << "? " << a[0] << " " << a[3] <<endl; fflush(stdout);
cin >> k;
if (k == 1) return a[0];
else return a[3];
}
if (k == 2) {
cout << "? " << a[1] << " " << a[2] <<endl; fflush(stdout);
cin >> k;
if (k == 1) return a[1];
else return a[2];
}
}
void solve(){
cin >> n;
for (int i = 1; i <= (1<<n); i++) {
v.pb(i);
}
while (v.size() > 2){
// cout<<v.size()<<endl; ////
while(!v.empty()){
a[0] = v.front();
v.pop_front();
a[1] = v.front();
v.pop_front();
a[2] = v.front();
v.pop_front();
a[3] = v.front();
v.pop_front();
int win = query();
tem.pb(win);
}
v = tem;
tem.clear();
}
if(v.size()==2){
cout << "? " << v[0] << " " <<v[1]<<endl; fflush(stdout);
cin >> k;
if (k == 1) v.pop_back();
else v.pop_front();
}
cout << "! " << v[0] <<endl; fflush(stdout);
}
int main(){
int t;cin >> t;
while (t--) {
v.clear(); tem.clear();
solve();
}
system("pause");
return 0;
}

浙公网安备 33010602011771号