题解:P14099 [POCamp 2022] 一安在?2 / Where's Waldo?
这道题感觉没有黑的难度,可能是交互的知识点占比太高了吧。
做法
因为数据是纯随机的,所以说不会有像 1 10 9 8 7 6 5 4 3 2 的唐人数据,那么句考虑处理区间的平均数,平均数小的话那么出现
询问的时候,我们在
那我们就开一个 struct 存储每一次查询,再开一个优先队列二分搜索。
struct Node {
ll l, r, sum;
Node(ll l, ll r, ll sum) : l(l), r(r), sum(sum) {}
bool operator<(const Node &a) const {
return a.sum * (r - l + 1) < sum * (a.r - a.l + 1);
}
};
priority_queue<Node> q;
剪枝
剪枝一:如果这个区间的和
剪枝二:如果当前区间
面向交互库编程
:::info[99 分代码]
// Problem: P14099 [POCamp 2022] 一安在?2 / Where's Waldo?
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P14099
// Memory Limit: 1024 MB
// Time Limit: 11000 ms
// Author: HoLuc1078
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define mem(a, b) memset(a, b, sizeof a)
#define M (N * 2)
using namespace std;
const int N = 1e5 + 10;
ll ask(ll l, ll r) {
cout << "? " << l << ' ' << r << '\n';
fflush(stdout);
ll x;
cin >> x;
return x;
}
struct Node {
ll l, r, sum;
Node(ll l, ll r, ll sum = 0) : l(l), r(r), sum(sum) {}
bool operator<(const Node &a) const {
return a.sum * (r - l + 1) < sum * (a.r - a.l + 1);
}
};
priority_queue<Node> q;
bool vis[N];
int main() {
ll T, n;
cin >> T >> n;
while (T--) {
mem(vis, 0);
while (!q.empty()) q.pop();
q.push(Node(1, n, ((n * (n + 1)) >> 1)));
while (!q.empty()) {
Node tmp = q.top();
q.pop();
ll l = tmp.l;
ll r = tmp.r;
ll sum = tmp.sum;
if (sum > ((n + n - r + l + 1) * (r - l) >> 1) + 1) continue;
if (r == l + 1 && vis[sum - 1]) continue;
ll mid = (l + r) >> 1;
ll x = ask(l, mid);
ll y = sum - x;
q.push(Node(l, mid, x));
q.push(Node(mid + 1, r, y));
if (l == mid) vis[x] = 1;
if (mid + 1 == r) vis[y] = 1;
if (l == mid && x == 1) {
cout << "! " << l << '\n';
fflush(stdout);
break;
}
if (mid + 1 == r && y == 1) {
cout << "! " << mid + 1 << '\n';
fflush(stdout);
break;
}
}
}
return 0;
}
:::
:::warning[注意]{open}
因为这道题是神秘交互库,所以这样交上去会卡
代码改进:
//if (sum > ((n + n - r + l + 1) * (r - l) >> 1) + 1) continue;
if (l == r || (r == l + 1 && sum > n + 1)) continue;
:::