Codeforces Round #427 (Div. 2) E. The penguin's game (交互题,二进制分组)
E. The penguin's game
Pay attention: this problem is interactive.
Penguin Xoriy came up with a new game recently. He has n icicles numbered from 1 to n. Each icicle has a temperature — an integer from 1 to 109. Exactly two of these icicles are special: their temperature is y, while a temperature of all the others is x ≠ y. You have to find those special icicles. You can choose a non-empty subset of icicles and ask the penguin what is the bitwise exclusive OR (XOR) of the temperatures of the icicles in this subset. Note that you can't ask more than 19 questions.
You are to find the special icicles.
Input
The first line contains three integers n, x, y (2 ≤ n ≤ 1000, 1 ≤ x, y ≤ 109, x ≠ y) — the number of icicles, the temperature of non-special icicles and the temperature of the special icicles.
Output
To give your answer to the penguin you have to print character "!" (without quotes), then print two integers p1, p2 (p1 < p2) — the indexes of the special icicles in ascending order. Note that "!" and p1 should be separated by a space; the indexes should be separated by a space too. After you gave the answer your program should terminate immediately.
Interaction
To ask a question print character "?" (without quotes), an integer c (1 ≤ c ≤ n), and c distinct integers p1, p2, ..., pc (1 ≤ pi ≤ n) — the indexes of icicles that you want to know about. Note that "?" and c should be separated by a space; the indexes should be separated by a space too.
After you asked the question, read a single integer — the answer.
Note that you can't ask more than 19 questions. If you ask more than 19 questions or at least one incorrect question, your solution will get "Wrong answer".
If at some moment your program reads - 1 as an answer, it should immediately exit (for example, by calling exit(0)). You will get "Wrong answer" in this case, it means that you asked more than 19 questions, or asked an invalid question. If you ignore this, you can get other verdicts since your program will continue to read from a closed stream.
Your solution will get "Idleness Limit Exceeded", if you don't print anything or forget to flush the output, including for the final answer .
To flush you can use (just after printing):
- fflush(stdout) in C++;
- System.out.flush() in Java;
- stdout.flush() in Python;
- flush(output) in Pascal;
- For other languages see the documentation.
Hacking
For hacking use the following format:
n x y p1 p2
Here 1 ≤ p1 < p2 ≤ n are the indexes of the special icicles.
Contestant programs will not be able to see this input.
Example input
4 2 1
2
1
1
output
? 3 1 2 3
? 1 1
? 1 3
! 1 3
Note
The answer for the first question is
.
The answer for the second and the third questions is 1, therefore, special icicles are indexes 1 and 3.
You can read more about bitwise XOR operation here: https://en.wikipedia.org/wiki/Bitwise_operation#XOR.
题意:
交互题,告诉你有 n (n<=1000) 个数(n 个数并不会告诉你),n 个数只含 x , y 两个数字,其中 y 只有两个。
可以对子集发起询问,对于你的每次询问会告诉你你所询问的子集的所有数的异或值,要求在19次询问内找到两个 y 的位置。
如:? 4 1 3 5 7 表示询问的子集包含四个元素{1, 3, 5, 7},则会返回{1, 3, 5, 7}所对应位置上的数字的异或值给你。
总结:
想了很长时间,题解也看了很长时间才有点头绪。
即:首先 n 个数按下标的二进制分成 10 个组(因为 n <= 1000,故 pow(2, 10) = 1024 > n)。
分组规则:对于一个下表 i (1 <= i <= n),可将其分在 i & (1 << bit) != 0 的组内,这样可保证每个数最多被分到 9 组;即对于每个数,它总会在某个集合中缺失。
这样就达到了将要找的两个 y 的分开的效果,可以保证存在这么两个组:分别包含不同的两个 y 。
对每个组可进行预处理,即可询问出两个 y 所在的组,设两个位置分别为 pos1、 pos2,通过预处理可求出 pos1 | pos2。
再对某个仅单独包含一个 y 的集合做二分查找,可求出一个 y 的位置,再通过异或求出另一个 y 的位置。
代码:
#include <bits/stdc++.h>
using namespace std;
int n, x, y;
int pos, pos1, pos2; int query(vector<int>& a)
{
int res=0;
if(a.size()!=0)
{
cout<<"? "<<a.size()<<" ";
for(int i=0; i<a.size(); ++i)
cout<<a[i]<<" ";
cout<<endl;
cin>>res;
}
return res;
} int slove(vector<int>& a)
{
int l=0, r=(int)a.size()-1;
while(l < r)
{
int m=(l+r)/2;
vector<int> b;
for(int i=l; i<=m; ++i)
b.push_back(a[i]);
int res=query(b);
if(res==y || res==(x^y))
r=m;
else
l=m+1;
}
return a[l];
} int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0); int bit=-1;
cin>>n>>x>>y;
for(int i=0; i<=9; ++i)
{
vector<int> a;
for(int j=1; j<=n; ++j)
if(j & (1<<i))
a.push_back(j);
int res=query(a);
if(res==y || res==(x^y))
{
pos |= (1<<i);
bit=i;
}
} vector<int> a, b;
for(int i=1; i<=n; ++i)
{
if(i & (1<<bit))
a.push_back(i);
else
b.push_back(i);
}
if(a.size() > b.size())
swap(a, b);
pos1=slove(a);
pos2=(pos^pos1);
if(pos1>pos2)
swap(pos1, pos2);
fflush(stdout);
cout<<"! "<<pos1<<" "<<pos2<<endl;
return 0;
}
Codeforces Round #427 (Div. 2) E. The penguin's game (交互题,二进制分组)的更多相关文章
- Codeforces Round #523 (Div. 2) F. Katya and Segments Sets (交互题+思维)
https://codeforces.com/contest/1061/problem/F 题意 假设存在一颗完全k叉树(n<=1e5),允许你进行最多(n*60)次询问,然后输出这棵树的根,每 ...
- CodeForces 835C - Star sky | Codeforces Round #427 (Div. 2)
s <= c是最骚的,数组在那一维开了10,第八组样例直接爆了- - /* CodeForces 835C - Star sky [ 前缀和,容斥 ] | Codeforces Round #4 ...
- CodeForces 835D - Palindromic characteristics | Codeforces Round #427 (Div. 2)
证明在Tutorial的评论版里 /* CodeForces 835D - Palindromic characteristics [ 分析,DP ] | Codeforces Round #427 ...
- Codeforces Round #368 (Div. 2) A. Brain's Photos (水题)
Brain's Photos 题目链接: http://codeforces.com/contest/707/problem/A Description Small, but very brave, ...
- Codeforces Round #427 (Div. 2) [ C. Star sky ] [ D. Palindromic characteristics ] [ E. The penguin's game ]
本来准备好好打一场的,然而无奈腹痛只能带星号参加 (我才不是怕被打爆呢!) PROBLEM C - Star sky 题 OvO http://codeforces.com/contest/835/p ...
- Codeforces Round #427 (Div. 2) Problem D Palindromic characteristics (Codeforces 835D) - 记忆化搜索
Palindromic characteristics of string s with length |s| is a sequence of |s| integers, where k-th nu ...
- Codeforces Round #427 (Div. 2) Problem C Star sky (Codeforces 835C) - 前缀和
The Cartesian coordinate system is set in the sky. There you can see n stars, the i-th has coordinat ...
- Codeforces Round #427 (Div. 2) Problem A Key races (Codeforces 835 A)
Two boys decided to compete in text typing on the site "Key races". During the competition ...
- Codeforces Round #427 (Div. 2) B. The number on the board
引子: A题过于简单导致不敢提交,拖拖拉拉10多分钟还是决定交,太冲动交错了CE一发,我就知道又要错过一次涨分的机会.... B题还是过了,根据题意目测数组大小开1e5,居然蒙对,感觉用vector更 ...
随机推荐
- 基于DDD+微服务的开发实战(1)
1 DDD是什么? DDD是领域驱动设计,是Eric Evans于2003年提出的,离现在有17年. 2 为什么需要DDD 当软件越来越复杂,实际开发中,大量的业务逻辑堆积在一个巨型类中的例子屡见不鲜 ...
- Linux高级命令进阶
输出重定向 场景:一般命令的输出都会显示在终端中,有些时候需要将一些命令的执行结果想要保存到文件中进行后续的分析/统计,则这时候需要使用到的输出重定向技术. >:覆盖输出,会覆盖掉原先的文件内容 ...
- netty字符串流分包
@Override protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf in, List<Obj ...
- hystrix(2) metrics
上一节讲到了hystrix提供的五个功能,这一节我们首先来讲hystrix中提供实时执行metrics信息的实现.为什么先讲metrics,因为很多功能都是基于metrics的数据来实现的,它是很多功 ...
- Final终态类和Finally
- 1.4Hadoop伪分布式安装
- Redis学习(四)redis发布订阅
文章更新时间:2020/04/22 一.简介 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. ...
- SQL注入之Mysql报错注入
--志向和热爱是伟大行为的双翼. 昨天偷懒了没学什么东西,先自我反省一下 - -. 今天认真的学习了一下Mysql报错注入利用方法及原理,好久之前就像认真的学一下这个了,是在上海市大学生网络安全大赛中 ...
- 关于VS编译报错,但是错误信息未提示问题解决方案
可能代码中引用了别的类库中的函数,然后未编译被引用库导致编译报错,重新编译被引用库然后再编译当前库即可解决问题
- 排序算法:冒泡排序(Bubble Sort)
冒泡排序 算法原理 冒泡排序的原理是每次从头开始依次比较相邻的两个元素,如果后面一个元素比前一个要大,说明顺序不对,则将它们交换,本次循环完毕之后再次从头开始扫描,直到某次扫描中没有元素交换,说明每个 ...