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;
}


你可能感兴趣的:(排序)