CSU 2258 思维+构造

http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2258

Description

Recall that a subsequence of a string is any string obtained by removing some subset of characters from the string, for instance "string", "sing", "i" and "sg" are all subsequences of "string". If the same subsequence can be obtained in exactly t different ways, by removing different subsets of characters, we say that the subsequence occurs t times.

Jingfei wants to create a nonempty bit string that has the following properties:

  1. the subsequence 00 occurs a times,

  2. the subsequence 01 occurs b times,

  3. the subsequence 10 occurs c times, and

  4. the subsequence 11 occurs d times.

However, Jingfei does not know how to create such a string -- or whether it is even possible. Could you help her?

Input

he input consists of a single line with four integers a, b, c, and d (0 ≤ a, b, c, d ≤ 109​).

Output

Output a bit string that satisfies the given requirements. If there are several solutions, output any one of them. If there are no solutions, output "impossible".

Sample Input

3 4 2 1
---------------------
5 0 0 5

Sample Output

01001
---------------------
impossible

Hint

Source

ncpc2018

题目大意:问你能否构造一个01序列,满足有a个00、b个01、c个10、d个11。(不要求连续 任意选择可得到即可)

思路:设有x个0,y个1,则a=x*(x-1)/2,(从x个0里面任选两个)同理得d=y*(y-1)/2,由此我们可解得x和y的值,(注意 当a=0或d=0时解出来的x和y不一定正确 因此要加上特判)现在我们知道有x个0和y个1了,假设cal(v)=v*(v-1)/2,那么给定的a、b、c、d应该满足:cal(x+y)-cal(x)-cal(y)=b+c,(即从x+y个元素中任选两个 除去全选1和全选0的情况 应该等于01 和10的数量之和)否则是无解的;那在满足的情况下如何构造01序列呢?我们考虑先一直放0,那么每放一个0对01的贡献就是y,因为后面还要放y个1,因此此时最多放b/y个0,那么01的贡献还差b%y个,我们令rest=b%y,放入y-rest个1,此时若rest=0,则继续放1,否则放入1个0,使01的数量满足题意然后继续把1放完,最后把剩下的0填上去即可。(这题自己做的时候好蠢 感觉x和y求错了然后WA到自闭)

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define EPS 1e-8
using namespace std;
typedef long long ll;

ll a,b,c,d;
ll x,y;

inline ll cal(ll v)
{
	return v*(v-1)/2;
}

inline ll Find(ll v)
{
	v*=2;
	ll i;
	for(i=1;;i++)
		if(i*(i-1)>v)
			break;
	--i;
	if(i*(i-1)==v)
		return i;
	return -1;
}

int main()
{
	scanf("%lld %lld %lld %lld",&a,&b,&c,&d);
	if(a==0&&b==0&&c==0&&d==0)
	{
		printf("0\n");
		return 0;
	}
	x=Find(a);
	y=Find(d);
	if(x==-1||y==-1)
	{
		printf("impossible\n");
		return 0;
	}
	if(a==0&&d==0)
	{
		if(b==1&&c==0)
			printf("01\n");
		else if(b==0&&c==1)
			printf("10\n");
		else
			printf("impossible\n");
		return 0;
	}
	if(b==0&&c==0)
	{
		if(a==0)
		{
			for(ll i=1;i<=y;i++)
				putchar('1');
			putchar('\n');
		}
		else if(d==0)
		{
			for(ll i=1;i<=x;i++)
				putchar('0');
			putchar('\n');
		}
		else
			printf("impossible\n");
		return 0;
	}
	if(cal(x+y)-cal(x)-cal(y)!=b+c)
		printf("impossible\n");
	else
	{
		 ll temp=b/y;
		 ll rest=b%y;
		 for(ll i=1;i<=temp;i++)
			putchar('0');
		 for(ll i=1;i<=y-rest;i++)
			putchar('1');
		 if(rest!=0)
		 {
			putchar('0');
			++temp;
		 }
		 for(ll i=1;i<=rest;i++)
			putchar('1');
		 for(ll i=temp+1;i<=x;i++)
			putchar('0');
		 putchar('\n');
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xiji333/article/details/89739476