题解 交互

传送门

手玩样例
发现 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;
	}
}
posted @ 2022-04-04 16:17  Administrator-09  阅读(3)  评论(0编辑  收藏  举报