• bzoj1293 生日礼物


    Description

    小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。 小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。

    Input

    第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。

    Output

    应包含一行,为最短彩带长度。

    对彩珠排序

    用一个数组记录当前区间每种颜色出现次数

    从左到右扫描结束位置,若得到合法结束位置则尽量右移起始位置,计算长度若更优则更新答案,起始位置右移一,重复本步

    #include<cstdio>
    #include<algorithm>
    inline int read(){
        int x=0,c=getchar();
        while(c>'9'||c<'0')c=getchar();
        while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
        return x;
    }
    int ts[64],t=0,ans=2147483647;
    struct p{
        int x,t;
    }ps[1000005];
    int pp=0;
    inline bool operator<(p a,p b){return a.x<b.x;}
    int n,k,m,x;
    int main(){
        n=read();k=read();
        for(int i=1;i<=k;i++){
            m=read();
            while(m--){
                x=read();
                ps[pp++]=(p){x,i};
            }
        }
        std::sort(ps,ps+pp);
        int l=0,r=0;
        while(1){
            while(t<k&&r<=n){
                if(!ts[ps[r++].t]++)t++;
            }
            if(r>n)break;
            while(1){
                if(!--ts[ps[l++].t]){
                    int v=ps[r-1].x-ps[l-1].x;
                    if(v<ans)ans=v;
                    t--;
                    break;
                }
            }
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    P1171 售货员的难题--搜索(剪枝)
    逆元-P3811 【模板】乘法逆元-洛谷luogu
    gcd和exgcd和lcm
    递推
    Docker hello workd
    Docker配置文件详解
    Centos7变动
    centos7安装docker
    nginx性能调优
    nginx相关
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5220266.html
Copyright © 2020-2023  润新知