CF1081F
设这个序列为 a。注意到连续操作 [i,i] 两次所形成的序列要么是 a,要么是除了 ai 都翻转的序列。我们可以多随几次,总能碰到第二种情况,然后就能知道第 i 个数是 0 还是 1 了,然后再还原回去。当然有一个问题就是除开 ai 以外剩下的 01 数量相等,这里我们可以把 [i,i] 改为 [i,i+1],这样每次能得到 ai+ai+1,最后再统计一下就可以了。这样我们就得到了一个期望 8n 次询问的做法。
Code:
#include <bits/stdc++.h>
using namespace std;
#define ff fflush(stdout)
const int N = 305;
int n, k;
int ans[N], a[N];
int ask(int l, int r) {
printf("? %d %d\n", l, r);
ff;
int res; scanf("%d", &res);
return res;
}
void print() {
printf("! ");
for (int i = 1; i <= n; ++i) printf("%d", ans[i]);
}
int work(int l, int r) {
int res;
do { res = ask(l, r), res = ask(l, r); } while (res == k);
int dis = res - (n - k);
do { res = ask(l, r), res = ask(l, r); } while (res != k);
return (r - l + 1 + dis) / 2;
}
int main() {
scanf("%d%d", &n, &k);
if (n == 2 * k + 1 || n == 2 * k - 1) {
for (int i = 1; i < n; ++i) a[i] = work(i, i + 1);
a[n] = 2 * k;
for (int i = 1; i < n; ++i) a[n] -= a[i];
for (int i = 1; i < n; ++i) {
if (i & 1) ans[n] -= a[i];
else ans[n] += a[i];
}
ans[n] = (ans[n] + a[n]) / 2;
for (int i = n - 1; i; --i) ans[i] = a[i] - ans[i + 1];
}
else for (int i = 1; i <= n; ++i) ans[i] = work(i, i);
print();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!