• D2. Kirk and a Binary String (hard version) D1 Kirk and a Binary String (easy version) Codeforces Round #581 (Div. 2) (实现,构造)


    D2. Kirk and a Binary String (hard version)
    time limit per test1 second
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    The only difference between easy and hard versions is the length of the string. You can hack this problem if you solve it. But you can hack the previous problem only if you solve both problems.

    Kirk has a binary string s (a string which consists of zeroes and ones) of length n and he is asking you to find a binary string t of the same length which satisfies the following conditions:

    For any l and r (1≤l≤r≤n) the length of the longest non-decreasing subsequence of the substring slsl+1…sr is equal to the length of the longest non-decreasing subsequence of the substring tltl+1…tr;
    The number of zeroes in t is the maximum possible.
    A non-decreasing subsequence of a string p is a sequence of indices i1,i2,…,ik such that i1<i2<…<ik and pi1≤pi2≤…≤pik. The length of the subsequence is k.

    If there are multiple substrings which satisfy the conditions, output any.

    Input
    The first line contains a binary string of length not more than 105.

    Output
    Output a binary string which satisfied the above conditions. If there are many such strings, output any of them.

    Examples
    inputCopy
    110
    outputCopy
    010
    inputCopy
    010
    outputCopy
    010
    inputCopy
    0001111
    outputCopy
    0000000
    inputCopy
    0111001100111011101000
    outputCopy
    0011001100001011101000
    Note
    In the first example:

    For the substrings of the length 1 the length of the longest non-decreasing subsequnce is 1;
    For l=1,r=2 the longest non-decreasing subsequnce of the substring s1s2 is 11 and the longest non-decreasing subsequnce of the substring t1t2 is 01;
    For l=1,r=3 the longest non-decreasing subsequnce of the substring s1s3 is 11 and the longest non-decreasing subsequnce of the substring t1t3 is 00;
    For l=2,r=3 the longest non-decreasing subsequnce of the substring s2s3 is 1 and the longest non-decreasing subsequnce of the substring t2t3 is 1;
    The second example is similar to the first one.

    题意:

    给你一个字符串s,只包含0,1两个字符,

    让你寻找一个字符串t,长度和s相等,并且0尽可能的多,

    同时满足 对于因为一个区间 l and r (1≤l≤r≤n) 两个字符串的最长不下降子序列长度相等。

    思路:

    我们首先来看下什么情况下会产生最长不下降子序列长度不相等。

    例如区间中:

    s:10
    t: 00

    显然s的长度为1,而t的为2,

    即有“10” 的位置才可能产生最长不下降子序列长度不相等。

    那么再来看长一点的

    s:1100

    t: 0100

    s 最长不下降子序列长度 为2 (11 或者 00)

    t:最长不下降子序列长度为3 (“000”)

    想让t的最长不下降子序列长度变小点

    我们可以把第一个0换成1,即也为1100

    再来看这个:

    s:01100

    t: 00100

    需要用1替换第二个0才满足条件。

    s:01111110

    t: 0000010

    就已经满足了条件,

    由此我们可以发现结论,

    当s和t同时从后向前扫,t中出现的1的个数大于等于s中出现0的个数才满足条件,满足条件的时候,t尽可能多填0.

    通过这个结论我们就很容易得出答案。

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int maxn=100010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    string str;
    struct node
    {
        int t;
        int num;
    }a[maxn];
    string ans="";
    int main()
    {
        //freopen("D:\common_text\code_stream\in.txt","r",stdin);
        //freopen("D:\common_text\code_stream\out.txt","w",stdout);
        cin>>str;
        int len=str.length();
        int cnt=0;
        for(int i=0;i<len;++i)
        {
            if(str[i]=='0')
            {
                int num=1;
                while((i+1)<len&&(str[i+1]=='0'))
                {
                    num++;
                    i++;
                }
                a[++cnt].t=0;
                a[cnt].num=num;
            }else
            {
                int num=1;
                while((i+1)<len&&(str[i+1]=='1'))
                {
                    num++;
                    i++;
                }
                a[++cnt].t=1;
                a[cnt].num=num;
            }
        }
        int need=0;
        for(int i=cnt;i>=1;--i)
        {
            if(a[i].t==0)
            {
                need+=a[i].num;
                repd(j,1,a[i].num)
                {
                    ans.push_back('0');
                }
            }else
            {
                int k=min(a[i].num,need);
                a[i].num-=k;
                need-=k;
                while(k--)
                {
                    ans.push_back('1');
                }
                repd(j,1,a[i].num)
                {
                    ans.push_back('0');
                }   
            }
        }
        reverse(ALL(ans));
        cout<<ans<<endl;
        
        
        
        return 0;
    }
     
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    MongoDB 基础命令 (MongoDB Shell)
    MongoDB 在 Mac OSX 平台安装
    数组根据index拆分和查询下标
    简单介绍递归算法以及应用场景
    android studio ndk开发环境搭建
    基于vue开发的多功能的时间选择器组件,开箱即用
    简单了解JS中的几种遍历
    零基础学习webpack打包管理
    让你高效的理解JavaScript中的同步、异步和事件循环
    学习flex布局(弹性布局)
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11386518.html
Copyright © 2020-2023  润新知