【CodeForces】708 B. Recover the String 数学构造

【题目】B. Recover the String

【题意】找到一个串s,满足其中子序列{0,0}{0,1}{1,0}{1,1}的数量分别满足给定的数a1~a4,或判断不存在。数字<=10^9,答案<=10^6。

【算法】数学构造

【题解】首先由a1和a4易得0的数量x0和1的数量x1。

容易发现01和10关系密切,令1的位置为b1...bx1,则:

{0,1} (b1-1)+(b2-2)+(b3-3)+...+(bx1-x1)=a2

{1,0} (x0-b1+1)+(x0-b2+1)+...+(x0-bx1+x1)=a3

两式相加,得x0*x1=a2+a3。

因此,只要满足表达式x0*x1=a2+a3,串就一定存在,此时只要随便构造b[]使得{0,1}数量符合,那么{1,0}数量就一定随之符合。

注意特殊处理0的情况。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<algorithm>
#define ll long long
#define lowbit(x) x&-x
using namespace std;
int read(){
    char c;int s=0,t=1;
    while(!isdigit(c=getchar()))if(c=='-')t=-1;
    do{s=s*10+c-'0';}while(isdigit(c=getchar()));
    return s*t;
}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a<b?b:a;}
int ab(int x){return x>0?x:-x;}
//int MO(int x){return x>=MOD?x-MOD:x;}
//void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
/*------------------------------------------------------------*/
const int inf=0x3f3f3f3f;

int n,a1,a2,a3,a4,x0,x1,b[1000010],c[1000010];
void p(){printf("Impossible");exit(0);}
int main(){
    scanf("%d%d%d%d",&a1,&a2,&a3,&a4);
    for(int i=1000000;i>=1;i--){
        if(1ll*i*(i-1)/2==a1)x0=i;
        if(1ll*i*(i-1)/2==a4)x1=i;
    }
    if(!x0||!x1)p();
    if(a2+a3==0){
        if(x0==1){
            for(int i=1;i<=x1;i++)printf("1");
            return 0;
        }
        if(x1==1){
            for(int i=1;i<=x0;i++)printf("0");
            return 0;
        }
    }
    if(x0*x1!=a2+a3)p();
    for(int i=1;i<=x1;i++)b[i]=i;
    for(int i=x1;i>=1;i--){
        if(a2>x0)b[i]=x0+i,a2-=x0;else{b[i]=a2+i;break;}
    }
    for(int i=1;i<=x1;i++)c[b[i]]=1;
    for(int i=1;i<=x1+x0;i++)printf("%d",c[i]);
    return 0;
}
View Code

 

posted @ 2018-01-17 07:04  ONION_CYC  阅读(208)  评论(0编辑  收藏  举报