Codeforces Round #846 (Div. 2)

题目链接

D

题意

给定一个数字n,我们需要通过一系列的操作去猜测这个数字。初始的时候会给我们一个cnt,表示二进制下数字n有多少个1.每次我们可以给出一个t,然后另n减去t,系统会给出来这个新的n的cnt。题目问我们原来的n是多少。

核心思路

这其实是一道简单的交互题。首先我们先从最基本的情况入手,我们想怎么确定最后一个位置的1.

我们使用cnt_cur表示现在的1的数目,cnt表示的是刚开始状态的1的数目.
n:10001001000
我们可以减去一个1,就变成了:
10001000111
我们可以发现cur_cnt-cnt=2,而我们的答案是3,所以我们先猜测这个结论是不是就是cur_cnt-cnt+1.
我们进一步模拟倒数第二个位置的情况。
一定要注意我们是根据前面的状态递推出来当前的。
所以我们再来分析10001000111怎么求出来倒数第二个位置。(我们需要知道是要我们求n的导数第二个,而不是这种变化了的状态。)
老样子,减去一个特殊位置的1,这个状态就变为了:
10000111111
cur_cnt-cnt+1=7-3+1=6;
// Problem: D. Bit Guessing Game
// Contest: Codeforces - Codeforces Round #846 (Div. 2)
// URL: https://codeforces.com/contest/1780/problem/D
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define NO {puts("NO") ; return ;}
#define YES {puts("YES") ; return ;}
//#define endl "\n"
#define int long long 


int ask(int num)
{
	cout<<"- "<<num<<endl;
	int x;
	cin>>x;
	return x;
}

void solve()
{
	int cnt;
cin>>cnt;
int bit=1;
int ans=0;
while(cnt)
{
	int cur_cnt=ask(bit);
	ans|=(1<<(cur_cnt-cnt+1));
	bit=1<<(cur_cnt-cnt+1);
	cnt--;
	
}
cout<<"! "<<ans<<endl;
}
signed main()
{
	
	int T=1;
	cin>>T;
	
while(T--)
{
	solve();
}


}

小tips:要记得关闭#define endl "/n".因为这个需要刷新缓存区,而我们的endl是刷新缓存区的。

posted @ 2023-01-27 21:23  努力的德华  阅读(54)  评论(0)    收藏  举报