[学習]アルゴリズムの足をエミュレート

ベーステンプレート

より大きいまたは小さいサブセグメントSに等しい和

ll sum=0;
int l=1,r=1;
while(true){
    //全速推进r指针
    while(r<=n && sum<s){
        sum+=a[r++];
    }
    //r走到头,sum无法再增大,答案无法更优
    if(sum<s){
        break;
    }
    //更新答案
    ans=min(ans,r-l);
    //龟速推进l指针
    sum-=a[l++];
}

POJ3061

タイトルの上にそのテンプレート

HDU5672

問題の意味

異なる文字の数がkよりも大きい文字列が与えられると、サブストリングの必要数は同じです。

分析

  • 手紙の異なる数/数も一般的に足のエミュレートに関連して。
  • 先にrに同じルーチン、フルスピード、文字の数をカウント表示され、異なる文字の数、そして累積答え、リットルを進め亀の速度を更新します。

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+50;
char s[N];
int T,k;
int cnt[30];
int main(){
//    freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        memset(cnt,0,sizeof(cnt));
        scanf("%s",s+1);
        scanf("%d",&k);
        int n=strlen(s+1);
        ll ans=0;
        int num=0;
        int l=1,r=1;
        while(true){
            while(r<=n && num<k){
                cnt[s[r]-'a']++;
                if(cnt[s[r]-'a']==1){
                    num++;
                }
                r++;
            }
            if(num<k){
                break;
            }
            ans+=(n-(r-1)+1);
            cnt[s[l]-'a']--;
            if(cnt[s[l]-'a']==0){
                num--;
            }
            l++;
            if(l>r){
                r=l+1;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

HDU5056

問題の意味

文字列が与えられると、列内に現れるすべての文字の必要数は、サブストリングの数がkに等しい未満です。

分析

  • 同じアイデアは足をエミュレートされていますが、文言は多少異なります。
  • \(CNTは\)また、各セクションの文字の現在の数、フルスピード維持\(R&LTの\)は、文字を追加していない\(S [R&LT]を\)場合、\(CNT [S [R] - [A 「] <= K \) 累積直接答え、そうでなければ、文字、削除\(R \)背中合わせには、事前の\(Lを\)

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+50;
char s[N];
int T,k;
int cnt[30];
int main(){
//    freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        memset(cnt,0,sizeof(cnt));
        scanf("%s",s+1);
        scanf("%d",&k);
        int n=strlen(s+1);
        ll ans=0;
        int l=1,r=1;
        while(l<=n){
            while(r<=n){
                cnt[s[r]-'a']++;
                if(cnt[s[r]-'a']<=k){
                    ans+=r-l+1;
                    r++;
                }else{
                    cnt[s[r]-'a']--;
                    break;
                }
            }
            cnt[s[l]-'a']--;
            l++;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/zxcoder/p/11355792.html