专栏文章
题解:CF2159A MAD Interactive Problem
CF2159A题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minlu5q1
- 此快照首次捕获于
- 2025/12/02 04:31 3 个月前
- 此快照最后确认于
- 2025/12/02 04:31 3 个月前
题解:CF2159A MAD Interactive Problem
关于交互题
每次输出完成之后需要刷新缓存区。为了刷新缓存区并换行,可以直接输出
std::endl。分析题意
需要我们求得的 数组是一个长度为 ,且 在数组中严格出现 次。
每次提问需要给出提问的下标,然后交互库会返回这些下标的 MAD 值。MAD 值的定义在题面已经给出。
接下来分析这个条件: 在数组中严格出现 次。那么我们可以构建两个集合 和 ,其中 中为对应值确定的下标, 中为对应值不确定的下标。我们还需要一个答案数组
最开始,下标 一定在集合 中。接下来从 开始遍历下标 直到 ,每次查询集合 中的所有元素和 。再读取交互库返回的值 ,如果 ,则可以得出
这一步执行完会提问 次。
接下来,从 开始遍历下标 直到 。如果下标 在集合 内,此时查询集合 中的所有元素和 ,并读取交互库返回的结果 ,则
当第一步执行完时,集合 与集合 中元素的数量一定都为 ,所以这一步执行完会提问 次。
最后一共提问 次,严格小于 。
每次提问需要给出提问的下标,然后交互库会返回这些下标的 MAD 值。MAD 值的定义在题面已经给出。
接下来分析这个条件: 在数组中严格出现 次。那么我们可以构建两个集合 和 ,其中 中为对应值确定的下标, 中为对应值不确定的下标。我们还需要一个答案数组
ans 来存储最终的答案。最开始,下标 一定在集合 中。接下来从 开始遍历下标 直到 ,每次查询集合 中的所有元素和 。再读取交互库返回的值 ,如果 ,则可以得出
ans[i] = x,并将 加入到集合 中。否则 ans[i] 不确定,并将 加入到集合 中。易证不会有其他情况。这一步执行完会提问 次。
接下来,从 开始遍历下标 直到 。如果下标 在集合 内,此时查询集合 中的所有元素和 ,并读取交互库返回的结果 ,则
ans[i] = x。由于在 中的元素对应的值不会重复出现,且元素对应的值严格包含 ,所以正确性显然。当第一步执行完时,集合 与集合 中元素的数量一定都为 ,所以这一步执行完会提问 次。
最后一共提问 次,严格小于 。
代码
CPP#include <bits/stdc++.h>
using namespace std;
void solve(){
int n;
cin >> n;
vector <int> known, unknown, ans(2 * n + 1);//known 对应集合 K,unknown 对应集合 U
unknown.emplace_back(1);
for(int i = 2; i <= 2 * n; i++){
cout << "? " << unknown.size() + 1 << ' ';
for(const auto &v : unknown)
cout << v << ' ';
cout << i << endl;
int x;
cin >> x;
if(x)
ans[i] = x, known.emplace_back(i);
else
unknown.emplace_back(i);
}
for(int i = 1; i <= 2 * n; i++){
if(!ans[i]){
cout << "? " << known.size() + 1 << ' ';
for(const auto &x : known)
cout << x << ' ';
cout << i << endl;
int x;
cin >> x;
ans[i] = x;
}
}
cout << "! ";
for(int i = 1; i <= 2 * n; i++)
cout << ans[i] << " \n"[i == 2 * n];
}
int main(){
int t;
cin >> t;
while(t--)
solve();
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...