ZOJ 3790 Consecutive Blocks 排序+扫描

来源:互联网 发布:如何评价张作霖 知乎 编辑:程序博客网 时间:2024/05/29 18:02

题目链接: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
原创粉丝点击