ZOJ月赛3790Consecutive Blocks(贪心)

时间:2021-07-06 18:19:07

题目地址:ZOJ 3790

题目大体意思是给你n个数的数列,还有k,在这n个数中删去最多k个数,使得得到的数列的最长连续数字最长,并输出这个数字。

大体思路是先排序进行预处理,然后定义两个指针,不断移动两个指针,找两个指针内满足条件的最大解。这样的话时间复杂度最大也是(n*logn(排序)+2*n(移动指针))。肯定不会超时。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <algorithm>

using namespace std;
struct node
{
int p, n;
} q[110000];
int cmp(node x, node y)
{
if(x.p==y.p)
return x.n<y.n;
return x.p<y.p;
}
int main()
{
int n, k, i, k2, x, j, y, max1, z;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i=0; i<n; i++)
{
scanf("%d",&x);
q[i].p=x;
q[i].n=i;
}
sort(q,q+n,cmp);
max1=-1;
k2=1;
z=1;
for(i=0; i<n; )
{
y=z;
for(j=k2; j<n; j++)
{
if(q[j].p!=q[i].p)
{
if(max1<y)
max1=y;
i=j;
k2=j+1;
z=1;
break;
}
if(q[j].n-q[i].n>j-i+k)
{
if(max1<y)
max1=y;
k2=j;
i++;
z=y-1;
break;
}
y++;
}
if(j==n)
{
if(max1<y)
max1=y;
break;
}
}
printf("%d\n",max1);
}
return 0;
}