CF708B Recover the String 构造

For each string s consisting of characters ‘0‘ and ‘1‘ one can define four integers a00, a01, a10 and a11, where axy is the number of subsequences of length 2 of the string s equal to the sequence {x,?y}.

In these problem you are given four integers a00, 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 than 1?000?000.

Input

The only line of the input contains four non-negative integers a00, a01, a10 and a11. Each of them doesn‘t exceed 109.

Output

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.

Examples

Input

Copy

1 2 3 4

Output

Copy

Impossible

Input

Copy

1 2 2 1

Output

Copy

0110

首先从a00和a11可以求出0和1的数量;

假设目前为0000...001111..;

显然a01=num0*num1,a10=0;

那么我们移动一个1去左边,a10++,a01--;但总数还是不变;

那么合理的解必须是a10+a01=num0*num1;

值得注意的是:当00或11=0时,0或1可能有1个也可能没有;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 1000005
#define inf 0x3f3f3f3f
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-3
typedef pair<int, int> pii;
#define pi acos(-1.0)
const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == ‘-‘) f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }

/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/
int a00, a01, a10, a11;

int main()
{
	//ios::sync_with_stdio(0);
	rdint(a00); rdint(a01); rdint(a10); rdint(a11);
	int k = 1, r = 1;
	while (k*(k - 1) / 2 < a00)k++;
	while (r*(r - 1) / 2 < a11)r++;
//	cout << k << ‘ ‘ << r << endl;
	int fg = 1;
	if (k*(k - 1) / 2 != a00 || r * (r - 1) / 2 != a11) {
		cout << "Impossible" << endl; return 0;
	}

	else if (a00 == 0 && a11 == 0) {
		if (a01 == 0 && a10 == 0)cout << 0 << endl;
		else if (a01 == 0 && a10 == 1)cout << "10" << endl;
		else if (a01 == 1 && a10 == 0)cout << "01" << endl;
		else cout << "Impossible" << endl;
		return 0;
	}
	else if (a00 == 0) {
		if (a01 == 0 && a10 == 0) {
			while (r--)cout << ‘1‘;

		}
		else if (a01 + a10 == r) {
			while (a10--)cout << ‘1‘;
			cout << 0;
			while (a01--)cout << ‘1‘;
		}
		else fg = 0;
	}
	else if (a11 == 0) {
		if (a10 == 0 && a01 == 0) {
			while (k--)cout << ‘0‘;
		}
		else if (a10 + a01 == k) {
			while (a01--)cout << 0;
			cout << 1;
			while (a10--)cout << 0;
		}
		else fg = 0;
	}

	else {
		if (a01 + a10 == k * r) {
			while (a01) {
				while (r > a01) {
					cout << 1;
					r--;
				}
				cout << 0;
				k--; a01 -= r;
			}
			while (r--)cout << 1;
			while (k--)cout << 0;
		}
		else fg = 0;
	}
	if (fg == 0)cout << "Impossible" << endl;
	return 0;
}

原文地址:https://www.cnblogs.com/zxyqzy/p/10127239.html

时间: 2024-12-27 13:21:11

CF708B Recover the String 构造的相关文章

cf708B. Recover the String---(构造法)

题目链接:http://codeforces.com/problemset/problem/708/B 意思是给出四个参数 a00表01串中00对的数量 a01表01串中01对的数量 a10表01串中10对的数量 a11表01串中11对的数量 求出一个符合条件的01串,如果不存在输出Impossible: 根据a00和a11可以求出0和1的个数:把cnt1个1放在前面,cnt0个0放在后面,此时的01串为0,当把0往前移动一位是01的个数会增加一,所以可以根据a01的个数移动0的位置: 当然在当

C++ string 构造的陷阱

先看代码 #include<iostream> #include<string> using namespace std; int main(int argc, char **argv) { string s = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + 'A'; cout<<s<<endl; return 0; }

hdu 4850 Wow! Such String! 构造 欧拉回路

Wow! Such String! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 934    Accepted Submission(s): 318 Special Judge Problem Description Recently, doge starts to get interested in a strange probl

UVALive - 7637 E - Balanced String(构造)

原题链接 题意:给出一个打乱顺序的序列,问是否能构造出一个括号匹配的字符串.每个数字为此前读取到的左括号数减去右括号数. 分析:有左括号开始构造,不够的话就找右括号.注意特殊情况待处理.详情看代码 #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<s

UVaLive 7637 Balanced String (构造)

题意:给定一个括号的序列,原先的序列是碰到左括号加1,碰到右括号减1,然后把序列打乱,让你找出字典序最小的一个答案. 析:直接从第一个括号判断就好了,优先判断左括号,如果不行就加右括号. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cma

codeforces 623A. Graph and String 构造

题目链接 给出一个图, 每个节点只有三种情况, a,b, c. a能和a, b连边, b能和a, b, c,连边, c能和b, c连边, 且无重边以及自环.给出初始的连边情况, 判断这个图是否满足条件. 由题意可以推出来b必然和其他的n-1个点都有连边, 所以初始将度数为n-1的点全都编号为b. 然后任选一个与b相连且无编号的点, 编号为1. 然后所有与1无连边的点都是3. 然后O(n^2)检查一下是否合理. #include <iostream> #include <vector>

hdu 4850 Wow! Such String! 构造 或 欧拉路径并改写成非递归版本

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4850 跟这道题也算是苦大仇深了... 题意:构造一个由26个小写字母组成的.无长度为4的重复子串的字符串(要求出能构造出的最大长度) 符合要求的长度为4的字符串有4^26个 容易猜最大长度是:4^26+3 = 456979 比赛的时候想法是要让各个字母出现得尽量“均匀” 用了一个cnt数组记录26个字母出现的次数 每次都选择出现次数最小的.不与前面重复的字母加上去 然而稍微写得有点歪,最后构造出了长

CodeForces 708B Recover the String

构造. 根据$a[0][0]$可以求得$0$的个数$p$,根据$a[1][1]$可以求得$1$的个数$q$. 如果找不到$p$或$q$,那么就无解. 每一个$0$放到序列中的任何一个位置,假设和前面的$1$产生了$x$对$10$,和后面的$1$产生了$y$对$01$,那么$x+y$一定等于$q$. 也就是说如果$p*q$不等于$a[0][1]+a[1][0]$,那么就无解了.否则只要将$1$一个一个放进序列中,凑成$1$前面的$0$的个数总和是$a[0][1]$就可以了. 上面的方法对一般的情况

【题解】Recover the String Codeforces 708B

题解讲的不是很详细,有些定理未加证明地直接给出,需要读者自己思考,如有不懂欢迎在讨论区提问 由00和11的个数可以确定0和1的个数假设00的个数是b,必须满足a*(a-1)/2=b,且a是整数这时候,a便是0的个数,求1的个数同理同时,01和10的个数的和 一定是 0的个数*1的个数然后构造一个00000000001111111111这样的串,是不存在10这样的子序列的我们称最右边的一坨1叫"没有交换的1",然后每次选择这里面最左边的一个1和第x(x待确定)个0交换注意到,和第x个0交