Codeforces Round 931 (Div. 2) D2

挺简单的题目,就是一个普通博弈论套了一个交互的皮。
。。但是恶心的就是,交互的皮是真难顶啊,什么sb玩意,我因为爆了int一直给我现实TLE on test 1,这我怎么调?
不得不说,交互题和普通的题目真是差别太大了,就评测这一块,返回的消息完全无法给我有效的指导。。然后我就直接坐大牢。
要是这题不套个交互的皮,难度顶天1600.。。我觉得。
而且这个交互的皮套的是真的生硬。。

其实对于一个数字的每一个二进制位置,我们考虑它是1和0两种情况。如果是1,那分为的两个数字的这一位就一定是0和1,如果是0,那分成的两个数字的对应位就是1,1或者0,0。那我们考虑我们什么时候能够赢。很简单,就是无法分解。手玩一下,发现是否能够分解和这个数字的二进制表示中的1的数量直接相关。如果二进制表示只有1个1,那就是无法分解。如果不止一个1,那就是一定能够分解。
观察分解的不同情况。我们发现,如果我们要构造一个必胜的情况,也就是电脑必败的情况,确实很简单,就是我们每次操作都让电脑能够选择的数字的二进制表示都只有奇数个1。要达到这个,我们一定分解的是含有偶数个1的数字。这样我们就能够分解出两个含有奇数个1的数字。而电脑只能够选择含有奇数个1的数字进行分解。可以发现,它只能够分解出来,一个二进制表示含有偶数个1的数字,和一个二进制表示含有奇数个1的数字。我们继续选择含有偶数个1的数字进行下一步操作。这就是我们的必胜态。

要保证我们必胜,就要保证我们什么时候能够拿到手的数字都是二进制表示含有偶数个1的数字。如果最开始给出的n不是,那我们就后手操作。
真的不难。。居然标了2400。。我可以说是理解了题意,手玩了一下就知道怎么做了。。一个1700的人能秒的题目。。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read(){
	ll a=0,b=1;char c=getchar();
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0';
	return a*b;
}
int count(ll x)
{
	int ans=0;
	for(int i=0;i<=62;i++)
	{
		ans+=((x>>i)&1);
//		cout<<((x>>i)&1)<<' ';
	}
//	cout<<endl;
	return ans;
}
int main()
{
	int T=read();
	while(T--)
	{
		ll n=read();
		if(count(n)%2==1)
			cout<<"second"<<endl;
		else
		{
			cout<<"first"<<endl;
			for(int i=60;i>=1;i--)
			{
				if(((n>>i)&1)==1)
				{
					cout<<(1LL<<i)<<' '<<(n-(1LL<<i))<<endl;
					break;
				}
			}
		}
		ll x1,x2;
		x1=read(),x2=read();
		while(x1!=0||x2!=0)
		{
			if(count(x1)%2==0)n=x1;
			else n=x2;
			for(int i=60;i>=1;i--)
			{
				if(((n>>i)&1)==1)
				{
					cout<<(1LL<<i)<<' '<<(n-(1LL<<i))<<endl;
					break;
				}
			}
			x1=read(),x2=read();
		}
	}
	return 0;
}

md,交互题是真恶心。

posted @ 2024-04-25 22:00  HL_ZZP  阅读(4)  评论(0编辑  收藏  举报