B. Recover the String(构造,注意边界)

不难想,但是边界特判真的搞死人

x 0 , 00 x ( x 1 ) / 2 设有x个0,那么00的组合就是x*(x-1)/2

0 1 所以0和1的个数可以直接求出来

01 10 那01和10的个数怎么办呢

x 0 , y 1 , 01 10 x y 设有x个0,y个1,那么01和10的个数和一定是x*y

因为每一个0都会和每一个1配对,配对结果会贡献给01或10

0 1 , 01 10 然后就可以把0插在1中间,满足01的个数就可以满足10的个数

/*
x个1形成x*(x-1)/2个  
111111 
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a,b,c,d;
map<int,int>mp;
signed main()
{
	mp[0]=1;
	for(int i=2;i*(i-1)/2<=1e9;i++)	mp[i*(i-1)/2]=i;
	cin >> a >> b >> c >> d;
	if( mp[a]==0||mp[d]==0 )	{ cout << "Impossible\n";return 0;}
	if( a+b+c+d==0 )//0,1都不存在 
	{
		cout << 0;
		return 0;
	}
	if( b+c+d==0 )//只存在0 
	{
		while(mp[a]--)	cout << 0;
		return 0;
	}
	if( a+b+c==0 )//只存在1 
	{
		while( mp[d]--)	cout << 1;
		return 0;
	}
	int zero=mp[a],one=mp[d];
	if( zero*one!=b+c )	cout << "Impossible\n";
	else
	{
		//考虑在1中插入0
		while(1)
		{
			if( one<=b )	cout << 0 ,zero--,b-=one;
			else	cout << 1 ,one--;
			if( b==0 )	break;
		}
		while( one-- )	cout << 1 ;
		while( zero-- )	cout << 0 ; 
	}
} 

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107881559