• AIM Tech Round 3 (Div. 2)D. Recover the String(贪心+字符串)


    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 exceed109.

    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

     比赛时,一直纠结怎么判断Impossible和构造字符串,胡乱交了一发,wa了,好SB。

    当然先是利用a00和a11求1和0的字符串个数g1和g0,如果a00或a11等于1,这时候还要根据a10和a01判断a00或者a11是等于1还是0.

    在求完a00和a11的个数后,判断合不合理,C(g0,2)=a00, C(g1,2)=a11, C(g1+g0,2) = a00+a01+a10+a11即成立。

    然后就是构造字符串了。

    设初始的字符串个数为0000001111111......

    然后就是贪心的构造字符串了。考虑该输出某一位时,如果在这一位时,a10>=g0,那么我可以把1挪到最前面,输出1,这时候后面剩下的字符串需要构造的a10-=g0,剩余的1的个数g1--。否则直接输出0,后面剩余字符串需要构造a01-=g1,剩余的0的个数g0--.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 typedef long long ll;
     8 int main()
     9 {
    10     ll a00,a01,a10,a11;
    11     scanf("%I64d%I64d%I64d%I64d",&a00,&a01,&a10,&a11);
    12     ll g0,g1;
    13     g0 = (1+sqrt(1+8*a00))/2;
    14     g1 = (1+sqrt(1+8*a11))/2;
    15     if(a00+a01+a10+a11==0)
    16     {
    17          printf("0
    ");
    18          return 0;
    19     }
    20     if(g0==1||g1==1)
    21     {
    22         if(g0==1)
    23         {
    24             if(a01||a10) g0 = 1;
    25             else g0 = 0;
    26         }
    27         if(g1==1)
    28         {
    29             if(a01||a10) g1 = 1;
    30             else g1 = 0;
    31         }
    32     }
    33     if(g0*(g0-1)!=2*a00||g1*(g1-1)!=2*a11)
    34     {
    35         printf("Impossible
    ");
    36         return 0;
    37     }
    38     ll gz = g0+g1;
    39     if(gz*(gz-1)/2!=(a00+a01+a10+a11))
    40     {
    41         printf("Impossible
    ");
    42         return 0;
    43     }
    44     while(g0+g1)
    45     {
    46         if(a10>=g0)
    47         {
    48             printf("1");
    49             a10 -= g0;
    50             g1--;
    51         }
    52         else
    53         {
    54             printf("0");
    55             a01 -= g1;
    56             g0--;
    57         }
    58     }
    59     printf("
    ");
    60     return 0;
    61 }
  • 相关阅读:
    idea 中使用 svn
    [剑指offer] 40. 数组中只出现一次的数字
    [剑指offer] 39. 平衡二叉树
    [剑指offer] 38. 二叉树的深度
    [剑指offer] 37. 数字在排序数组中出现的次数
    [剑指offer] 36. 两个链表的第一个公共结点
    [剑指offer] 35. 数组中的逆序对
    vscode在win10 / linux下的.vscode文件夹的配置 (c++/c)
    [剑指offer] 34. 第一个只出现一次的字符
    [剑指offer] 33. 丑数
  • 原文地址:https://www.cnblogs.com/littlepear/p/5809907.html
Copyright © 2020-2023  润新知