这是一个互动的问题。Kira有一个隐藏的正整数n, hayyato需要猜出来。最初,Kira给Hayato的值是cnt——二进制表示n的单位比特数。要猜出n, Hayato只能做一种操作:选择一个整数,然后用n减去它。注意,每次操作后,数字n都会发生变化。吉良不喜欢糟糕的请求,所以如果隼人试图减去一个大于n的数字,他就会输给吉良。在每次操作之后,Kira将更新后的值cnt(更新后的值n的二进制表示中的单位比特数)给Hayato。Kira没有太多耐心,所以hayyato必须在不超过30次的操作后猜测n的原始值。因为hayyato在上小学,他请求你的帮助。写一个程序来猜测数字n。基拉是一个诚实的人,所以他在所有操作之前都选择初始数字n,之后不改变它。输入输入数据包含几个测试用例。第一行包含一个整数t (1 t <500)测试用例的数量。测试用例的描述如下。每个测试用例的第一行包含数字cnt——二进制表示的单位位的初始数目n。隐藏整数n满足以下约束:1 < n < 109。交互要猜出n,最多可以执行30次操作。要做到这一点,打印一行以下格式:"- x" (1 < x < 10°)。在这个操作之后,n减去z,因此n改变了。如果数字z大于当前值n,则认为请求无效。操作结束后,读取包含单个非负整数cnt的一行——操作结束后,当前n的二进制表示的单位比特数。当你知道n的初始值时,打印一行,格式如下:"!N " (1 < N < 10°)。在此之后,继续进行下一个测试用例,如果没有测试用例,则终止程序。如果您的程序对一个测试用例执行了超过30个操作,减去了一个大于n的数字z,或者发出了一个错误的请求,那么对请求的响应将是-1,在收到这样的响应后,您的程序必须立即退出以接收错误答案判决。否则,你可以得到其他判决。
Example
input
Copy
3 1 0 1 1 0 2 1 0
output
Copy
- 1 ! 1 - 1 - 1 ! 2 - 2 - 1 ! 3
请注意例如,数字6的单位位数是2,因为6的二进制表示法是110。对于13,单位比特数是3,因为1310 = 11012.在第一个测试用例中,n = 1,因此输入是数字1。n减1后,它变成0,所以它的单位比特数是0.l在第三个测试案例中,n=3,在二进制表示中看起来像310 112,所以输入是1的个数,也就是2。减去2后,n = 1,所以单位比特数现在是1。n减1后,它等于0。请注意,输入和输出示例中的空行是为了清晰起见而显示的,在实际交互中没有出现。
注意:交互式问题输入输出只能用c++的输入输出!!!
题解:
我们从二进制0位开始询问某位是否有1即可,由于状态会不断改变,记录一下上次变换的值,下次减掉,就能做到只有单个位置发生变化,
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
using namespace std;
//#define int long long
const int N = 2e6 + 10;
typedef pair<int, int> PII;
typedef long long ll;
void solve()
{
int n;
cin >> n;
int t = 0;
int ans = 0;
int cnt = 0;
for(int i = 0;i <= 30;i++)
{
int x = (1 << i);
cout <<"- "<<x - t <<"\n";
// printf("- %d\n",x - t);
int a;
cin >> a;
// scanf("%d",&a);
if(a == n - 1)
{
ans += x;
cnt ++;
}
if(cnt == n)
{
cout <<"! "<<ans<<"\n";
// printf("! %d\n",ans);
return ;
}
t = x;
}
}
//1 2 4
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
cin >> t;
//scanf("%d",&t);
while (t--)
{
solve();
}
}
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//0 1 1 1 1
//0 1 1 1 1