题解 CF1552H 【Guess the Perimeter】
Description
平面直角坐标系中有一个两边都平行于
你可以进行
最后输出这个长方形的周长。
Solution
没人写,那就我来捡漏啦。本场(并不)完全题解:https://www.cnblogs.com/-Wallace-/p/sol-cf-gr15.html
对于一个
首先有一个还算显然的引理:记询问一个点集
根据这个,可以判断一个数
考虑求一个
形式化上面的描述,就一个等式:
最后就是如何求
至于
Code
#include <algorithm>
#include <iostream>
#include <vector>
const int MaxU = 200;
int area, f[10]; // f[i] = f(2^i)
int apply(int td) {
int d = (1 << td);
std::vector<std::pair<int, int>> p;
for (int i = d; i <= MaxU; i += d)
for (int j = 1; j <= MaxU; j++)
p.emplace_back(i, j);
std::cout << "? " << p.size() << std::endl;
for (auto [x, y] : p)
std::cout << x << " " << y << std::endl;
int res = 0;
std::cin >> res;
return f[td] = res;
}
signed main() {
area = f[0] = apply(0);
int best = 0, l = 1, r = 7;
while (l <= r) {
int mid = (l + r) >> 1;
if (apply(mid) * (1 << mid) == area)
best = mid, l = mid + 1;
else r = mid - 1;
}
int h = std::abs(f[best] - f[best + 1] * 2) - 1;
int w = area / (h + 1) - 1;
std::cout << "! " << (w + h) * 2 << std::endl;
return 0;
}