2020ICPC・Xiaomiネットワークトライアルトーナメント第2回(質問2020)

ポータル

題名

文字列SSを与えるS∣S∣ <= 1 e 5 | S | <= 1e5| S |<=1 e 5)、文字列には「0」、「1」、「2」の3文字しかありません。ばらばらのサブシーケンス「2020」の最大数はいくつですか。

回答

「2020」の特徴を見ると、左右の構造が同じなので、最初の「20」の弦の数と2番目の「20」の弦の数という2つの同じサブ問題に分解して、それらを組み合わせることができます。答えです。問題は、最初の「20」文字列をいくつ構成するかをどのように判断するかです。暴力的な列挙は明らかに受け入れられません。現時点では、二分法を考える必要があります。二分法を使用する場合は、最初に、それが二分法の単調な性質を満たしているかどうかを判断する必要があります。考えて、調べてください。XXを形成できる場合X「2020」サブシーケンスも明らかにX− 1X-1を形成できますバツ1「2020」サブシーケンス、それ以外の場合はXXを形成できない場合X「2020」サブシーケンスは明らかにX + 1 X +1に結合できませんバツ+1つのサブシーケンス。

したがって、それは二分された性質と一致し、最初の「20」文字列の番号が二分されます。つまり、二分された答えです。特定の手順については、コードを参照してください。

ACコード

/*******************************
*   Coder : He Shuo.           *
*   Type : Original Work       *
*******************************/
#pragma GCC optimize("O3")
#pragma G++ optimize("O3")

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 55;

int n;
char s[MAXN];

int check(int x)
{
    
    
    int a1 = x,a2 = 0,a3 = 0,a4 = 0;
    ///a1 表示第一个"20"字符中2还需要多少个,a2则是'0'还需要多少个
    ///a3 表示第二个"20"字符中2还需要多少个,a4则是'0'还需要多少个
    
    for(int i = 1;i <= n;i ++)
    {
    
    
        if(s[i] == '2')
        {
    
    
            if(a1)a1 --,a2 ++;///来了一个'2',优先把第一个"20"中的'2'达成数量要求;
            else if(a3)a3 --,a4 ++;///达成之后就填第二个"20"的'2';
        }
        else if(s[i] == '0')
        {
    
    
            if(a2)a2 --,a3 ++;///来了一个'0',也是优先把第一个"20"中的'0'达成数量要求;
            else if(a4)a4 --;///达成之后就填第二个"20"的'0';
        }
    }
    if(a1 == 0 && a2 == 0 && a3 == 0 && a4 == 0)return 1;///所有数量都达成之后说明当前x符合条件
    return 0;///否则就不行
}

int main()
{
    
    
	while(scanf("%d",&n) + 1)
    {
    
    
        scanf("%s",s + 1);
        int l = 0,r = n / 4;///答案边界为[0,n/4],很显然的吧。
        while(l < r)
        {
    
    
            int mid = l + r >> 1;
            if(check(mid))l = mid + 1;
            else r = mid;
        }
        if(check(l) == 0)l --;///看看当前l符不符合,不符合就答案减一(本蒟蒻二分就喜欢这么写,保险一点)
        printf("%d\n",l);
    }

}

おすすめ

転載: blog.csdn.net/qq_43814654/article/details/109407083