题目链接:https://vjudge.net/problem/Gym-101933J
主要参考:https://www.cnblogs.com/wangzhebufangqi/p/11309965.html
https://blog.csdn.net/tianyizhicheng/article/details/83301634
题意:输入a,b,c,d,分别代表00、01、10、11的数量,让你构造出一个字符序列。
思路:可以根据组合公式推出0、1的个数分别为x、y。这里有一个结论:如果能够构造出来,那么x*y=b+c。好像是挺好理解的。先进行一系列的特判,再把0放入。接下来计算1的插入位置。假如有n个0,1的插入位置为p,那么增加的10数目为n-p,增加的01数目为p。
#include <bits/stdc++.h>
using namespace std;
long long solve(long long x)//根据组合公式可以得出方程组x*(x-1)=a
{
x*=2;
long long i=1;
for(;; i++)
{
if(i*(i-1)>x)
break;
}
i--;
if(i*(i-1)==x)
return i;
return -1;
}
int main()
{
long long a,b,c,d;
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
if(!a&&!b&&!c&&!d)//如果全为0的情况
{
printf("0\n");
return 0;
}
long long x=solve(a),y=solve(d);
if(x==-1||y==-1)//没有解的情况
{
printf("impossible\n");
return 0;
}
if(x==1&&y==1)//只有一个0一个1的情况
{
if(b&&c)
{
printf("impossible\n");
}
else if(b==1)
{
printf("01\n");
}
else if(c==1)
{
printf("10\n");
}
else if(b==0&&c==0)
{
printf("impossible\n");
}
else
{
printf("impossible\n");
}
return 0;
}
else if(x==1)//当输入a=0时,x才会=1 也就是说没有00 那么也就是说
{ //x可以为0或者1 又因为没有10 01,x必须为0
if(b==0&&c==0)
x=0;
}
else if(y==1)
{
if(b==0&&c==0)
y=0;
}
if(x*y!=b+c)
{
printf("impossible\n");
return 0;
}
string s;
for(int i=0; i<x; i++)//先把0放入
{
s+='0';
}
long long left=b;//还需要增加多少01
while(y--)
{
long long e=min(left,x);//防止越界的情况
s.insert(e,"1");
left-=e;
}
cout<<s<<endl;
return 0;
}