ZOJ 3790 Consecutive Blocks 排序+扫描

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3790

http://vjudge.net/contest/view.action?cid=52151#problem/C


1.题意:

一个给你一个长度为N的序列,每一位上有一个数字代表一种颜色。给你0~K个操作,有每一步操作可以移除某个位置上的数字,求同一个数字连续最长为多少。


2.题解:

(1)把每一个数字单独考虑,他可以得到的最大连续长度只与自己的位置,以及K有关。

(2)把每一种颜色单独考虑他操作0~K步可以得到的答案,更新最大值。

(3)先排序,把数字相同的按照原先的位置关系排好。

(4)对于相同颜色的,用一个头指针,一个尾指针扫一遍,计算答案。


code:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Node{
    int c,p;
    bool operator<(const Node& rhs)const{
        if(c!=rhs.c) return c<rhs.c;
        return p<rhs.p;
    }
}s[111111];
int N,K;
int cal(int st,int ed){
    int k=0,sum=0,ret=0;
    for(int p=st,q=st;q<=ed;){
        if(k<=K){
            sum++;
            ret=max(ret,sum);
            k+=s[q+1].p-s[q].p-1;
            q++;
        }else{
            sum--;
            k-=s[p+1].p-s[p].p-1;
            p++;
        }
    }
    return ret;
}
int main()
{
//    freopen("data.in","r",stdin);
    while(scanf("%d%d",&N,&K)==2){
        int i,j;
        for(i=0;i<N;s[i].p=i++)
            scanf("%d",&s[i].c);
        sort(s,s+N);
        int ans=0;
        for(i=0;i<N;i=j+1){
            int c=s[i].c;
            j=i;
            while(j+1<N && s[j+1].c==c) j++;
            ans=max(ans,cal(i,j));
        }
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值