• 2020ICPC·小米 网络选拔赛第二场 A-2020(二分答案)


    2020ICPC·小米 网络选拔赛第二场 A-2020(二分答案)

    题面:

    题意:

    给定一个只含有(0,1,2)的字符串,现在问你可以把字符串最多分成多少个互不相交的子序列,其中每一个子序列是(2020).

    思路:

    在区间([0,frac{n}{4}]) 中二分答案,对于当前的需要check的答案(mid)

    我们如下进行验证:

    先找到(mid)个字符( ext 2),然后对于每一个( ext 2)找到其后方最近的( ext 0) 分给它作成(20)

    然后对于每一个( ext 20)找到其后方最近的( ext 2) 分给它,作成(202)

    ,然后对于每一个( ext 202)找到其后方最近的( ext 0) 分给它作成(2020)

    若能完成则返回true,否则为false。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for (int i=a;i<=n;++i)
    #define per(i,n,a) for (int i=n;i>=a;--i)
    #define sz(x) ((int)(x).size())
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define lson l,mid,p<<1
    #define rson mid+1,r,p<<1|1
    typedef pair<int, int> pii;
    #define ll long long
    const int inf = 1e9;
    const int mod = 1e9 + 7;
    const int N = 1e6 + 10;
    int n;
    char s[N];
    int vis[N];
    int vis1[N];
    int vis2[N];
    int used[N];
    bool check(int mid)
    {
        for (int i = 1; i <= n; ++i) {
            vis[i] = 0;
            vis1[i] = 0;
            vis2[i] = 0;
            used[i] = 0;
        }
        int num = 0;
        for (int i = 1; i <= n; ++i) {
            if (s[i] == '2') {
                if (num < mid) {
                    num++;
                    vis[i] = 1;
                    used[i] = 1;
                }
            }
        }
        if (num < mid) {
            return 0;
        }
        num = 0;
        int cnt = 0;
        for (int i = 1; i <= n; ++i) {
            cnt += vis[i];
            if (s[i] == '0' && used[i] == 0) {
                if (cnt > 0 && num < mid) {
                    cnt--;
                    num++;
                    vis1[i] = 1;
                    used[i] = 1;
                }
            }
        }
        if (num < mid) {
            return 0;
        }
        num = 0;
        cnt = 0;
        for (int i = 1; i <= n; ++i) {
            cnt += vis1[i];
            if (s[i] == '2' && used[i] == 0) {
                if (cnt > 0 && num < mid) {
                    cnt--;
                    num++;
                    used[i] = 1;
                    vis2[i] = 1;
                }
            }
        }
        if (num < mid) {
            return 0;
        }
        num = 0;
        cnt = 0;
        for (int i = 1; i <= n; ++i) {
            cnt += vis2[i];
            if (s[i] == '0' && used[i] == 0) {
                if (cnt > 0 && num < mid) {
                    cnt--;
                    num++;
                    used[i] = 1;
                }
            }
        }
        return num >= mid;
    }
    int main()
    {
        //ios::sync_with_stdio(false);
        //freopen("in","r",stdin);
        while (~scanf("%d", &n)) {
            scanf("%s", s + 1);
            int l = 0;
            int r = n / 4;
            int mid;
            int ans = 0;
            while (l <= r) {
                mid = (l + r) >> 1;
                if (check(mid)) {
                    ans = mid;
                    l = mid + 1;
                } else {
                    r = mid - 1;
                }
            }
            printf("%d
    ", ans );
        }
        return 0;
    }
    
    
  • 相关阅读:
    ubuntu 制做samba
    《Programming WPF》翻译 第4章 前言
    《Programming WPF》翻译 第4章 3.绑定到数据列表
    《Programming WPF》翻译 第4章 4.数据源
    《Programming WPF》翻译 第5章 6.触发器
    《Programming WPF》翻译 第4章 2.数据绑定
    《Programming WPF》翻译 第4章 1.不使用数据绑定
    《Programming WPF》翻译 第5章 7.控件模板
    《Programming WPF》翻译 第5章 8.我们进行到哪里了?
    《Programming WPF》翻译 第5章 5.数据模板和样式
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/13907861.html
Copyright © 2020-2023  润新知