题解 交互
手玩样例
发现 1 号点是没有左子树的
考虑划分子问题
现在我们要处理点 \(i\) 的左子树形态已知,要求出 \(i\) 的右子树
考虑 \(i+1\) 在哪
若 \(i+1\) 在 \(i\) 的右子树中,则 \(i+1\) 没有左儿子
若 \(i+1\) 是 \(i\) 的父亲,那 \(i+1\) 就是 \(i\) 的父亲
怎么判断一个 \(j\) 是不是 \(i\) 的右子树的根呢?
递归子问题可以求出 \(j\) 的右子树
若 \(j\) 是 \(i\) 右子树的根那么 \(i\) 子树的形态就确定了
query 一下看是不是即可
点击查看代码
#include "interact.h"
#include <bits/stdc++.h>
#define fir first
#define sec second
int my_n;
std::pair<int, int> solve(int l, int fa, int left_of_fa) {
// std::cout<<"solve: "<<l<<std::endl;
int r=l, now=l, top;
while (1) {
if (!query(now, l, now)) {
std::pair<int, int> t=solve(now+1, now, l);
report(now, t.fir);
top=t.sec+1; r=t.sec;
}
else top=now+1;
if (top!=my_n+1 && !query(fa, left_of_fa, top-1)) {
report(now, top);
now=top; r=top;
}
else return {now, r};
}
}
void guess(int n) {
my_n=n;
int now=1, top;
while (1) {
if (!query(now, 1, now)) {
std::pair<int, int> t=solve(now+1, now, 1);
report(now, t.fir);
top=t.sec+1;
}
else top=now+1;
if (top!=n+1) {
report(now, top);
now=top;
}
else break;
}
}