AIM Tech Round 3 (Div. 2) -- D. Recover the String (思路题目--构造字符串)

78 篇文章 0 订阅
49 篇文章 0 订阅

大体题意:

给你一个只包含01的字符串,告诉你00,01,10,11子字符串的个数,还原这个字符串!

思路:

好恶心的一道题目,本来比赛已经推出来了,但是时间只有几分钟了!  比赛完 又不断wa样例  又写了一小时终于过了!

只能说自己想的还不够全面,不能把自己代码错误想全面,还要在努力!

这个题目实际有规律的!

先根据00 和11的个数 能够确定 最终字符串0的个数和1的个数!  就是一个排列组合 在n0个0中选择2个就是a,逆推解一下一元二次方程即可!

用n0表示0 的个数和n1表示1的个数!

假设我们的输入 是abcd,全都大于0!

那么我们可以先给一个初始状态,在移动1的位置!

初始状态我写的是先写n0个0,在写n1个1,然后按顺序移动每一个1,算一算会发现,每左移1个1,01个数减一,10个数加1,根据这个规律,我们可以一位一位的移动,当然数据比较大,直接算出距离 交换一下就好!

在移动过程中,10和01个数总和是不变的,因此我们可以 b + c不等于 那个总和的话,就Impossible了!,否则就一定能移动到b 个01和c个10

需要注意的是,就是在这个移动过程中边界1的处理。

在一点注意的是,输入数据中会0的数据,对于这种样例,我把每一种有0的可能都讨论了一遍!  (看代码水平了 = =!)

最后参考一下我的代码吧:(写的很乱很乱)

#include<bits/stdc++.h>
#define fi first
#define se second
#define ps push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
const int maxn = 100000 + 10;
const double eps = 1e-10;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
ll f(ll x){
    return x*(x-1)/2;
}
int main(){
    ll a,b,c,d;
    cin >> a >> b >> c >> d;
    //=====================================================
    //单独讨论a是0,b也是0 
    if (!a && !d){
		if (b == 1 && c == 0)printf("01\n");
		else if (b == 0 && c == 1)printf("10\n");
		else if (b == 0 && c == 0)printf("0\n");
		else printf("Impossible\n");
		return 0;
	}
	//====================================================== 
    ll n0 = (ll)((1+sqrt(1+8*a))/2);
    ll t = n0,t2 = n0+1,t3 = n0-1;
    if (f(t) != a && f(t+1) != a && f(t-1) != a){
        printf("Impossible\n");
        return 0;
    }

    if (f(t-1) == a) n0 = t-1;
    else if (f(t) == a)n0 = t;
    else n0 = t+1;

    ll n1 = (ll)((1+sqrt(1+8*d))/2);
    t = n1,t2 = n1+1,t3 = n1-1;
    if (f(t) != d && f(t+1) != d && f(t-1) != d){
        printf("Impossible\n");
        return 0;
    }
    if (f(t-1) == d) n1 = t-1;
    else if (f(t) == d)n1 = t;
    else n1 = t + 1;
	// 上面这一片区域是求出n0,n1  0的个数和1的个数  解一元二次方程  n0*n0-n0-2a = 0; 
//================================================================= 
    if (b +c != n0*n1 && n0 && n1){
        printf("Impossible\n");
        return 0;
    }else if (b+c!=n0*n1 && !n0 && n1){
    	if (b+c != n1)printf("Impossible\n");
    	else {
    		for (int i = 0; i < c; ++i)printf("1");
    		printf("0");
    		for (int i = 0; i < b; ++i)printf("1");
    		puts("");
		}
    	return 0;
	}else if (b+c!=n0*n1 && n0 && !n1){
		if (b+c!=n0)printf("Impossible\n");
		else {
			for (int i = 0; i < b; ++i)printf("0");
    		printf("1");
    		for (int i = 0; i < c; ++i)printf("0");
    		puts("");
			
		}
		return 0;
	}else if (b+c!=n0*n1 && !n0 && !n1){
		printf("Impossible\n");
		return 0;
	}
	// 上面这一片区域是单独讨论数据abcd哪一个是0! 
    //=============================================================================
    
    //  下面就是通解  算出有多少个1 在最左边,中间有多少0,中间是否有1,右边的0!
	//  需要注意边界1的问题!!!!! 
    ll b2 = n0*n1-b;
    for (int i = 0 ; i < (!n0?0:(b2/n0)); ++i)printf("1");
    ll len = !n0?0:b2%n0;
    for (int i = 0; i < n0-len; ++i)printf("0");
   if (n1-(!n0?0:(b2/n0)))printf("1");
    for (int i = 0; i < len; ++i)printf("0");
    for (int i = 0; i < n1-((!n0?0:(b2/n0))+1); ++i )printf("1");
    puts("");
    return 0;
}





D. Recover the String
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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
1 2 3 4
Output
Impossible
Input
1 2 2 1
Output
0110


Codeforces

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值