zoukankan      html  css  js  c++  java
  • J-Jumbled String(2018NCPC)

    VJ上题目链接:https://vjudge.net/problem/Kattis-jumbledstring 

    看题目以为是关于字符串匹配的,理解后发现原来是关于计数的?

    给定a、b、c、d四个整数,求一个01串,要求该串能找到a个00,b个01,c个10,d个11。(子序列,不必连续)

    根据a个00是能求出0的个数x的,因为x个0组成的串中任意拿两个0即是C(x,2)=x*(x-1)/2个。1的个数y同理可求。

    即解方程x*x-x-2*a=0和y*y-y-2*d=0。有一个无解则"impossible"。

    接下来是安排01和10。

    求出x和y后就能知道所有的长度为2的子序列个数即C(x+y,2),又长度为2的子序列的个数和是a+b+c+d,联立上式可得:b+c=x*y。若不满足则impossible。满足则说明有解。

    只考虑01和10,每将1个'1'排在p个'0'后会增加p个01的子序列,x-p个10的子序列。

     1 #include<iostream>
     2 #include<sstream>
     3 #include<fstream>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<iomanip>
     7 #include<cstdlib>
     8 #include<cctype>
     9 #include<vector>
    10 #include<string>
    11 #include<cmath>
    12 #include<ctime>
    13 #include<stack>
    14 #include<queue>
    15 #include<map>
    16 #include<set>
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define random(a,b) (rand()%(b-a+1)+a)
    19 #define ll long long
    20 #define ull unsigned long long
    21 #define e 2.71828182
    22 #define Pi acos(-1.0)
    23 #define ls(rt) (rt<<1)
    24 #define rs(rt) (rt<<1|1)
    25 #define lowbit(x) (x&(-x))
    26 using namespace std;
    27 ll read()
    28 {
    29     int s=1,x=0;
    30     char ch=getchar();
    31     while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();}
    32     while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();}
    33     return x*s;
    34 }
    35 ll cal(ll ad)//x*x-x-2*a=0
    36 {
    37     if(ad==0) return 1;
    38     ll delta=sqrt(1+8*ad);
    39     if(delta*delta!=1+8*ad) return -1;
    40     return (1+delta)/2;
    41 } 
    42 int main()
    43 {
    44     ll a=read(),b=read(),c=read(),d=read(); 
    45     if(a==0&&b==0&&c==0&&d==0) return 0*printf("0
    "); 
    46     ll x=cal(a),y=cal(d);
    47     if(x==-1||y==-1) return 0*printf("impossible
    ");
    48     if(x==1&&y==1)
    49     {
    50         if(b&&c)    printf("impossible
    ");
    51         else if(b==1)    printf("01
    ");
    52         else if(c==1)    printf("10
    ");
    53         else if(b==0&&c==0) printf("0
    ");
    54         else printf("impossible
    ");
    55         return 0;
    56     }
    57     else if(x==1)
    58     {
    59         if(b==0&&c==0)x=0;
    60     }
    61     else if(y==1)
    62     {
    63         if(b==0&&c==0)y=0;
    64     }
    65     if(x*y!=b+c) return 0*printf("impossible
    ");
    66     string ans(x,'0');
    67     ll left_01=b;//还有left_01个子序列未构成 
    68     while(y--)
    69     {
    70         ll ip=min(left_01,x);//insert_pos == 01
    71         ans.insert(ip,"1");//因为ip是非递增的,所以这里用insert不用担心 
    72         left_01-=ip;
    73     }
    74     cout<<ans<<endl;
    75 }
    View Code

    (注意特判一些特殊情况)

  • 相关阅读:
    [NOI Online 2021 提高组] 愤怒的小N
    [NOI Online 2021 提高组] 积木小赛
    「2020-2021 集训队作业」Yet Another Permutation Problem
    无标号有根树/无根树 计数
    无向图的 三元环
    有标号二分图计数
    有标号荒漠计数
    「雅礼集训 2018 Day8」B
    CF708E Student's Camp
    清华集训 2016 选做
  • 原文地址:https://www.cnblogs.com/wangzhebufangqi/p/11309965.html
Copyright © 2011-2022 走看看