题目原文:
For each strings consisting of characters '0' and '1' one can define four integersa00,a01,a10 and a11, where axy is the number of subsequences of length2 of the strings equal to the sequence{x, y}.
In these problem you are given four integersa00,a01,a10,a11 and have to find any non-empty string s that matches them, or determine that there is no such string. One can prove that if at least one answer exists, there exists an answer of length no more than1 000 000.
The only line of the input contains four non-negative integersa00,a01,a10 and a11. Each of them doesn't exceed 109.
If there exists a non-empty string that matches four integers from the input, print it in the only line of the output. Otherwise, print "Impossible". The length of your answer must not exceed 1 000 000.
解题思路:根据题意可知可以借助00,11的数量来计算出序列中 0 和 1 的个数。这两个值必须是(n-1)*n/2这种格式的数。明确0和1的数目后再来匹配01的数目和10的数目。我们先假设所有的1位于一起。考虑如果让01,10的数目同时合法。只有放置在所有1两侧的0,对彼此的数目不产生影响。
可以证明的是如果这个串是可以得到的,那么最多只有1个0插在所有的1之间就可以得到答案。
设1的个数为k 设 b = m*k + x c = n*k + y (带余除法)如果有满足题意的解则 k |b + c(有整除关系) // 因为b+c 等于 0的个数×1的个数。
那么只需要在1之间插入一个0,保证这个0前面有x个1就可以了~
考虑这么一组数据 3 5 4 3
可以知道这组数据里面有三个1,三个0。我们先将三个1放置在一起。然后考虑10,01.
- 111
- 0111 //01数目多于1的数目往前放置0
- 01101 //为了凑齐01的数目需要往1之间插入0
- 011010 //把剩下的0放在后面,如果满足条件输出答案
/*
@Author: wchhlbt
@Date: 2017/2/23
*/
#include <bits/stdc++.h>
#define Fori(x) for(int i=0;i<x;i++)
#define Forj(x) for(int j=0;j<x;j++)
#define maxn 100005
#define inf 0x3f3f3f3f
#define ONES(x) __builtin_popcount(x)
using namespace std;
typedef long long ll ;
const double eps =1e-8;
const int mod = 20071027 ;
typedef pair<int, int> P;
const double PI = acos(-1.0);
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int ans;
int zero,one;
int pos[maxn];
int main()
{
//freopen("test.txt","r",stdin);
ios_base::sync_with_stdio(false);
cin.tie(0);
int a,b,c,d;
cin>>a>>b>>c>>d;
if((a+b+c+d)==0){
cout << 0 << endl;
return 0;
}
for(ll i = 1; i<=1e5; i++){
if((i-1)*i/2==a)
zero = i;
if((i-1)*i/2==d)
one = i;
}
if((c+b)==0){
if(a==0)
{
if(d==1) cout << 11 ;
else if(one==0){
cout << "Impossible" << endl;
return 0;
}
else
for(int i = 0; i<one; i++)
cout << 1 ;
cout << endl;
}
else if(d==0)
{
if(a==1) cout << "00";
else if(zero==0){
cout << "Impossible" << endl;
return 0;
}
else
for(int i = 0; i<zero; i++)
cout << 0 ;
cout << endl;
}
else
cout << "Impossible" << endl;
return 0;
}
int i;
for(i = 1; i<=zero; i++)
{
if(b==0)
break;
if(b>=one){
b -= one;
}
else{
pos[i] = (one-b);
c -=(one-b);
b = 0;
}
}
for(int j = i; j<=zero; j++){
if(c==0) break;
pos[j] = one;
c -= one;
}
if(b!=0 || c!=0 || (zero+one)==0)
{
cout << "Impossible" << endl;
return 0;
}
for(int k = 1; k<=zero; k++)
{
for(int j = pos[k-1]; j<pos[k]; j++){
cout << 1;
one--;
}
cout << 0;
}
while(one--) cout << 1;
cout << endl;
return 0;
}