UOJ 578收集卡片

Posted wuhu-jjj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;

 

以上是关于UOJ 578收集卡片的主要内容,如果未能解决你的问题,请参考以下文章

UOJ #578. 收集卡片

#578. 收集卡片

MotoGP Ignition 卡片收集专家版

当保持在一条线上时收集总价值最大的卡片(仅从角落提取)[重复]

Trello 如何在 MongoDB 中存储数据? (每板收集?)

[Sdoi2008]Sandy的卡片