题目:点击进入
描述:
对一个01字符串,给出他的四个描述:00、01、10、11子串的个数,求是否能构造出这样的一个串,不能则输出Impossible。01串长度不超过1e6,子串数不超过1e9.
题解:
通过计数我们可以得出,如果一个串的0的个数是num0,那么00子串的个数就是n*(n-1)/2(1+……+n-1),11子串同理。而且每个子串的个数不超过1e9,那么解一元二次不等式就可以知道0/1的个数是不超过1e5的,所以可以通过枚举求出0和1的个数。
由组合可知01子串和10子串的总数就是num0 * num1,这是第一个检验答案合法性的。其次num0 + num1 <= 1e6。最后num0和num1不能为初始值-1.
为什么不设为0?
因为存在这样的非空串,num00 num01 num10 num11都是0,如1或0都满足,所以要特判。
最后是构造部分。
首先是01子串,对于一个0,对01的贡献是在这之后的num1的值,所以每构造一个0,num01都要减一个num1, 10同理。
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define MP(A, B) make_pair(A, B)
#define pb push_back
#define gcd __gcd
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
typedef long long ll;
typedef unsigned long long ulls;
typedef unsigned int uint;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vii;
typedef map<int, int> mii;
typedef map<string, int> msi;
typedef map<pii, int> mpi;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const int MOD = 1e9 + 7;
const double pi = acos(-1.0);
const double eps = 1e-6;
const int maxn = 1e6 + 5;
const int maxm = 1e6 + 5;
const int dx[] = {-1, 0, 1, 0, -1, -1, 1, 1};
const int dy[] = {0, 1, 0, -1, 1, -1, 1, -1};
inline int scan(int &a) { return scanf("%d", &a); }
inline int scan(int &a, int &b) { return scanf("%d%d", &a, &b); }
inline int scan(int &a, int &b, int &c) { return scanf("%d%d%d", &a, &b, &c); }
inline int scan(ll &a) { return scanf("%I64d", &a); }
inline int scan(ll &a, ll &b) { return scanf("%I64d%I64d", &a, &b); }
inline int scan(ll &a, ll &b, ll &c) { return scanf("%I64d%I64d%I64d", &a, &b, &c); }
inline int scan(double &a) { return scanf("%lf", &a); }
inline int scan(double &a, double &b) { return scanf("%lf%lf", &a, &b); }
inline int scan(double &a, double &b, double &c) { return scanf("%lf%lf%lf", &a, &b, &c); }
inline int scan(char &a) { return scanf("%c", &a); }
inline int scan(char *a) { return scanf("%s", a); }
template<class T> inline void mem(T &A, int x) { memset(A, x, sizeof(A)); }
template<class T0, class T1> inline void mem(T0 &A0, T1 &A1, int x) { mem(A0, x), mem(A1, x); }
template<class T0, class T1, class T2> inline void mem(T0 &A0, T1 &A1, T2 &A2, int x) { mem(A0, x), mem(A1, x), mem(A2, x); }
template<class T0, class T1, class T2, class T3> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x); }
template<class T0, class T1, class T2, class T3, class T4> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x), mem(A4, x); }
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x), mem(A4, x), mem(A5, x); }
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void mem(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6, int x) { mem(A0, x), mem(A1, x), mem(A2, x), mem(A3, x), mem(A4, x), mem(A5, x), mem(A6, x); }
template<class T> inline T min(T a, T b, T c) { return min(min(a, b), c); }
template<class T> inline T max(T a, T b, T c) { return max(max(a, b), c); }
template<class T> inline T min(T a, T b, T c, T d) { return min(min(a, b), min(c, d)); }
template<class T> inline T max(T a, T b, T c, T d) { return max(max(a, b), max(c, d)); }
template<class T> inline T min(T a, T b, T c, T d, T e) { return min(min(min(a,b),min(c,d)),e); }
template<class T> inline T max(T a, T b, T c, T d, T e) { return max(max(max(a,b),max(c,d)),e); }
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
long _begin_time = clock();
#endif
ll num00, num01, num10, num11; scan(num00, num01, num10); scan(num11);
ll num0 = -1, num1 = -1;
for(ll i = 0; i < maxn; i++)
{
if(i * (i - 1) / 2 == num00)
{
num0 = i;
break;
}
}
for(ll i = 0; i < maxn; i++)
{
if(i * (i - 1) / 2 == num11)
{
num1 = i;
break;
}
}
if(num01 || num10)
{
if(num0 == 0) num0++;
if(num1 == 0) num1++;
}
if((num0 == -1 || num1 == -1) || (num0 + num1 > 1e6) || (num0 * num1 != num01 + num10)) puts("Impossible");
else
{
if(num0 == 0 && num1 == 0) puts("0");
else
{
while(num0 || num1)
{
if(num01 >= num1 && num0 > 0)
{
printf("0");
num01 -= num1;
num0--;
}
else
{
printf("1");
num1--;
}
}
printf("\n");
}
}
#ifndef ONLINE_JUDGE
long _end_time = clock();
printf("time = %ld ms\n", _end_time - _begin_time);
#endif
return 0;
}