【UOJ 578】收集卡片

【题目描述】:

Star计划订购一本将要发行的周刊杂志,但他可不是为了读书而是集卡。

已知杂志将要发行N周(也就是N期),每期都会附赠一张卡片。Star通过种种途径,了解到N期杂志附赠的卡片种类。Star只想订购连续的若干期, 并在这些期内收集到所有可能出现的种类的卡片。现在他想知道,最少需要订 购多少期。

【输入描述】:

第一行一个整数 N;

第二行一个长度为 N 的字符串,由大写或小写字母组成,第 i 个字符表示第i 期附赠的卡片种类,每种字符(区分大小写)表示一种卡片。

【输出描述】:

输出一行一个整数,表示 Star 最少订购的期数。

【样例输入】:

8
acbbbcca

【样例输出】:

3

【样例说明】:

【时间限制、数据范围及描述】:

时间:1s 空间:256M

对于 30%的数据,N≤300;

对于 40%的数据,N≤2000;

对于 60%的数据,N≤5000;

对于 80%的数据,N≤100000;

对于100%的数据,N≤500000。

题解:搞了半天原来是二分出了问题,换了种二分就能过了,开心。

           考试的时候80,怎么也想不通,唉。

#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
const int N=500002;
char s[N],c;
bool f[66];
int v[66];
int n,a[N],m,bili;
int Yao_Chen(int len){
    //for(int l=m;l<=n;l++){
        memset(v,0,sizeof(v));
        int now=0;
        for(int i=1;i<=len;i++){
            if(v[a[i]]==0) now++; 
            v[a[i]]++;
        }
            
        //if(l==6) cout<<v[27]<<' '<<v[28]<<' '<<now<<endl;        
        if(now==m) return 1;//return l;
        /*for(int i=2;i<=n-m+1;i++){
            if(--v[a[i-1]]==0) now--;
            if(++v[a[i+len-1]]==1) now++;
            //if(l==6) cout<<v[27]<<' '<<v[28]<<' '<<now<<endl;    
            if(now==m) return 1;//return l;
        }*/
        for(int i=len+1;i<=n;i++){
            //--b[a[i-u]];
             if(--v[a[i-len]]==0) --now;
            //++b[a[i]];
            if(++v[a[i]]==1) ++now;
            if(now==m) return 1;
        }
    //}
    return 0;
}

int work(){
    int l=m,r=n,mid,jj;
    while(l<=r){
        mid=(l+r)/2;
        //bili=Yao_Chen(mid);
        if(Yao_Chen(mid)) {
            r=mid-1; jj=mid;
        }
        else l=mid+1;
    }
    return jj;
}

void init(){
    scanf("%d",&n); scanf("%s",s+1);
    for(int i=1;i<=n;i++){
        if(s[i]>='A' && s[i]<='Z') a[i]=s[i]-'A'+1;
        else a[i]=s[i]-'a'+27;
        if(f[a[i]]==0) { f[a[i]]=1; m++; }
        //cout<<a[i]<<' ';
    }
}

int main(){
    freopen("c.in","r",stdin);
    freopen("c.out","w",stdout);
    init(); printf("%d",work());
    return 0;
}
原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11517995.html