「杂题乱刷2」CF862D

简单题。

题目链接

CF862D Mahmoud and Ehab and the binary string

解题思路

首先我们可以发现,字符串的第一个字母不是 1 就是 0,因此我们可以容易花费 2 次询问来找到数字 0 或数字 1 所在的一个位置。

然后,显然的,我们以先找到的数字为 0 为例,那么我们就可以先询问一个全为 0 的字符串,然后通过构造前 Mid 位为 1,其余都为 0 的字符串来二分出第一个 1 的位置,因为你会发现,如果这个字符串与全为 0
的字符串的权值差为 Mid,那么前 Mid 为都为 0,反之,前 Mid 位必然有至少一个 1,因此我们可以通过二分来确定,而先找到的数字为 1 也是同理。

综上,询问次数为 3+logn 次,可以通过此题。

参考代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;
//#define map unordered_map
#define re register
#define ll long long
#define forl(i,a,b) for(re ll i=a;i<=b;i++)
#define forr(i,a,b) for(re ll i=a;i>=b;i--)
#define mid ((l+r)>>1)
#define lowbit(x) (x&-x)
#define pb push_back
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
//#define endl '\n'
#define QwQ return 0;
ll _t_;
void _clear(){}
ll n;
string ans;
string S;
ll get(string s)
{
	ll sum=0;
	forl(i,0,n-1)
		sum+=s[i]!=ans[i];
	return sum; 
}
ll ask(string s)
{
	cout<<"? "<<s<<endl;
	ll x;//=get(s);
	cin>>x;
	return x;
}
string f(ll x)
{
	string SS="";
	forl(i,1,x)
		SS+='0';
	forl(i,x+1,n)
		SS+='1';
	return SS;
}
string f2(ll x)
{
	string SS="";
	forl(i,1,x)
		SS+='1';
	forl(i,x+1,n)
		SS+='0';
	return SS;	
}
ll ans0,ans1;
void solve()
{
	_clear();
	cin>>n;
	forl(i,1,n)
		S+='0';
	ll q1=ask(S);
	S[0]='1';
	ll q2=ask(S);
	if(q1>q2)
		ans1=1;
	else
		ans0=1;
	S="";
	forl(i,1,n)
		S+='1';
	ll q3=ask(S);
	if(!ans0)
	{
		ll L=1,R=n;
		while(L<R)
		{
			ll Mid=(L+R)/2;
			if(ask(f(Mid))==q3+Mid)
				L=Mid+1;
			else
				R=Mid; 
		}
		cout<<"! "<<L<<' '<<ans1<<endl;
	}
	else
	{
		ll L=1,R=n;
		while(L<R)
		{
			ll Mid=(L+R)/2;
			if(ask(f2(Mid))==q1+Mid)
				L=Mid+1;
			else
				R=Mid; 
		}
		cout<<"! "<<ans0<<' '<<L<<endl;		
	}
	
}
int main()
{
//	IOS;
	_t_=1;
 //	cin>>_t_;
	while(_t_--)
		solve();
	QwQ;
}
posted @   wangmarui  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示