您的位置:首页 > 大数据 > 人工智能

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

2016-08-25 04:21 603 查看
大体题意:

给你一个只包含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;
}



[align=center]D. Recover the String[/align]

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: