码迷,mamicode.com
首页 > 其他好文 > 详细

[SinGuLaRiTy] 2017-03-30 综合性测试

时间:2017-04-01 01:30:17      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:数列   任务   整数   logs   log   str   ring   algorithm   相同   

【SinGuLaRiTy-1014】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.

对于所有的题目:Time Limit:1s  |  Memory:256 MB

第一题:完美序列

【题目描述】

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

【输入】

第一行两个整数N,K

接下来N行,每行1个整数,表示第i个数。

【输出】

最长的完美序列的长度。

【样例数据】

样例输入 样例输出

9 1

2

7

3

7

7

3

7

5

7

4

 

 

 

 

 

 

 

 

 

 

 

 

【STD Code】

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
using namespace std;
int ans;
int kind[200000];
struct node
{
    int value;
    int pos;
};
node data[200000];
int cmp_value(node a,node b)
{
    return a.value<b.value;
}
int cmp_origin(node a,node b)
{
    return a.pos<b.pos;
}
int main()
{
    int n,k;
    int t,now,contain,l;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
      scanf("%d",&data[i].value);
      data[i].pos=i;
    }
    sort(data+1,data+n+1,cmp_value);
    now=1;
    t=data[1].value;
    for(int i=1;i<=n;i++)
        if(data[i].value==t)
            data[i].value=now;
        else
        {
            now+=1;
            t=data[i].value;
            data[i].value=now;
        }
    sort(data+1,data+n+1,cmp_origin);
    contain=0;
    l=1;
    for(int i=1;i<=n;i++)
    {
        if((kind[data[i].value]==0)&&(contain<=k))
        {
            contain+=1;
            kind[data[i].value]+=1;
            ans=max(ans,kind[data[i].value]);
        }
        else if((kind[data[i].value]==0)&&(contain>k))
        {
            kind[data[i].value]+=1;
            kind[data[l].value]-=1;
            while(kind[data[l].value]!=0)
            {
                l+=1;
                kind[data[l].value]-=1;
            }
            l+=1;
            ans=max(ans,kind[data[i].value]);
        }
        else
        {
            kind[data[i].value]+=1;
            ans=max(kind[data[i].value],ans);
        }
    }
    printf("%d",ans);
    return 0;
}

 【题目分析】

别的先不说,看到仅有100000个数字,数据范围却是1000000000,就说明我们首先要对这个序列进行离散化。在这里,可以开一个结构体,定义两个值:value和pos,value表示值,pos表示这个数原本在序列的哪一个位置,先用一次sort对value进行排序,更改值的大小(也就是离散化的中心操作),接着再来一次sort,按pos排序,以此将序列的位置排布还原为原来的序列。

下面,我们就来看看这道题的中心思路:设置一个“移动窗口”。也就是说,定义两个变量:L,R,来记录可能答案的潜在区间。在最开始,我们将L,R初始化为0,即L,R将从序列的最左端开始向右扫描。由于题目中有要求“仅能删除k类数”,那么,当窗口刚刚开始移动时,我们可以先保持L不动,使R右移,与此同时,不断更新在该窗口内存在的数的种类(当然,你也要算出此时的最优解),当种类达到k+1种时,就说明当前区间已经塞满啦,此时要想继续使窗口移动,就要使L+=1,更新之后,再让R+=1......以此类推,不断使窗口移动下去,直到扫描至序列末端,此时的答案就是整个序列中的完美序列的最优解了。

[SinGuLaRiTy] 2017-03-30 综合性测试

标签:数列   任务   整数   logs   log   str   ring   algorithm   相同   

原文地址:http://www.cnblogs.com/SinGuLaRiTy2001/p/6653979.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!