• 3048: [Usaco2013 Jan]Cow Lineup


    原题:http://www.lydsy.com/JudgeOnline/problem.php?id=3048

    Description

     Farmer John's N cows (1 <= N <= 100,000) are lined up in a row. Each cow is identified by an integer "breed ID" in the range 0...1,000,000,000; the breed ID of the ith cow in the lineup is B(i). Multiple cows can share the same breed ID. FJ thinks that his line of cows will look much more impressive if there is a large contiguous block of cows that all have the same breed ID. In order to create such a block, FJ chooses up to K breed IDs and removes from his lineup all the cows having those IDs. Please help FJ figure out the length of the largest consecutive block of cows with the same breed ID that he can create by doing this.

    给你一个长度为n(1<=n<=100,000)的自然数数列,其中每一个数都小于等于10亿,现在给你一个k,表示你最多可以删去k类数。数列中相同的数字被称为一类数。设该数列中满足所有的数字相等的连续子序列被叫做完美序列,你的任务就是通过删数使得该数列中的最长完美序列尽量长。

    Input

    * Line 1: Two space-separated integers: N and K. 
    * Lines 2..1+N: Line i+1 contains the breed ID B(i). 

    Output

    * Line 1: The largest size of a contiguous block of cows with identical breed IDs that FJ can create.

    Sample Input

    9 1 









    INPUT DETAILS: There are 9 cows in the lineup, with breed IDs 2, 7, 3, 7, 7, 3, 7, 5, 7. FJ would like to remove up to 1 breed ID from this lineup. 

    Sample Output


    OUTPUT DETAILS: By removing all cows with breed ID 3, the lineup reduces to 2, 7, 7, 7, 7, 5, 7. In this new lineup, there is a contiguous block of 4 cows with the same breed ID (7). 

    HINT

    样例解释:
    长度为9的数列,最多只能删去1类数。
    不删,最长完美序列长度为2.
    删去一类数3,序列变成2 7 7 7 7 5 7,最长完美序列长度为4.因此答案为4.
    题解:思路如下,我们要删去k类数,后找到最长完美子序列,其实就是找一个区间里面有k+1类数,这个区间中数量最多的那个数就是这段区间删去k类数后能形成的最长完美子序列。所以我们只要去构成一个队列,不停地往队尾加数,同时去更新当前队列能构成最长完美子序列的长度,若加入一个数后,这个队列里面的数的种类超过了k+1种,则我们就开始删去对首的元素,直到队列中数的种类小于等于k+1种为止。
      特别提醒的是,打着打着会发现,因为要记录下每种数的个数,导致数组会开得太大,然后就。。。。。
      怎么处理?我们会发现对于每个数,我们只要知道它们哪几个是同一种数就行了,跟他们本身没多大关系,所以这里在开始的时候通过排序把它离散化一下,数组就能开了。
    具体程序注释:
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int ans,n,k,t,now,num,l,b[200000];
    struct h{
        int x,y;
    }a[200000];
    int cmp1(const h&a,const h&b)
    {
         return (a.x<b.x);
    }
    int cmp2(const h&a,const h&b)
    {
         return (a.y<b.y);
    }
    int main()
    {
        cin>>n>>k;
        for (int i=1;i<=n;i++) 
        {
          cin>>a[i].x;
          a[i].y=i;//记录下原数的位置
         //因为我用了排序,所以这个是为了把数离散化以后再排回来用的
        }
        sort(a+1,a+1+n,cmp1);//排序
        now=1;   t=a[1].x;
        for (int i=1;i<=n;i++) //标号
        if (a[i].x==t) a[i].x=now;
        else
        {
          now+=1;
          t=a[i].x;
          a[i].x=now;
        }
        sort(a+1,a+1+n,cmp2);//排回来。。。
        num=0;
        l=1;
        for (int i=1;i<=n;i++)
        if ((b[a[i].x]==0)&&(num<=k))//如果当前这种数在队列中还一个都没有,且队列中数的种类小于等于k种,即小于k+1种
        {
            num+=1;//数的种类加一
            b[a[i].x]+=1;//队列中这种数的个数加一
            ans=max(ans,b[a[i].x]);//更新答案
        }
        else if ((b[a[i].x]==0)&&(num>k))
    //当前这种数还未在队列中出现,但是队列中已经有k+1个数了
        {
          b[a[i].x]+=1;//我们还是要把这种数加进来
          b[a[l].x]-=1;//删去队首元素
          while (b[a[l].x]!=0)//直到整个队列中减去了一种元素,即当前被删的队首元素在整个队列中已没有同种种类的元素了。
          {
              l+=1;
              b[a[l].x]-=1;
          }
          l+=1;
          ans=max(ans,b[a[i].x]);
        }
        else 
        {
         b[a[i].x]+=1;//把这个数加进来
         ans=max(b[a[i].x],ans);
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    一步一步学习IdentityServer4 (4) 处理特殊需求之-登录等待页面
    php 打包下载
    nginx https反向代理tomcat
    the "ssl" parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf
    layui配置
    vue 学习一
    MyCAT+MySQL 搭建高可用企业级数据库集群——第3章 MyCat核心配置讲解
    第一模块·开发基础-第3章 作业讲解
    《扭转人生的40个哲学提问》 徐帆 著
    零基础学 JavaScript 全彩版 明日科技 编著
  • 原文地址:https://www.cnblogs.com/2014nhc/p/6274016.html
Copyright © 2020-2023  润新知