Consecutive Blocks (ZOJ3970)

来源:互联网 发布:finereport数据查询 编辑:程序博客网 时间:2024/06/16 02:49

给出n个带着颜色的方块,然后最多去掉k块,求最长的连续颜色段。

如1122322,去掉3则最长是4,另外113311去掉33最长则是4。

思路是先把所有的颜色排到一起,再去一次遍历得到符合条件的(去掉小于等于k块)最大连续段。

难点:

1.关于把所有的颜色放到一起,可以开许多个vector把相同的颜色放到同一个vector,也可以自己写cmp排在一起,操作起来大同小异。

2.关于怎么一次扫过之后得到最大连续段。那么,我们存进去的都是这个颜色块的位置。例如1,3,6,8,。如果k为3,那么先(1)->(1,3)这时候已经用掉了1块了->(1,3,6)这时候用掉了3块相同颜色串为3->(1,3,6,8(不满足))这时候用超了,所以去掉最左边的,所以应该对应的状态是->(3,6,8)任何数据都同理模拟。在过程中不断更新最大值就是最长长度

#include<bits/stdc++.h>using namespace std;struct node{    int color,pos;} a[100005];long long n,m,k;bool cmp(node x,node y){    if(x.color!=y.color)return x.color<y.color;//颜色小的放前面    return x.pos<y.pos;//位置小的放前面}int main(){    while(cin>>n>>k)    {        for(int i=0; i<n; i++)//保存每个数据的颜色,以及这个节点的位置        {            cin>>a[i].color;            a[i].pos=i;        }        sort(a,a+n,cmp);//颜色相同的排在一起,同时位置小的优先        int ans=1,cnt=1,temp=k,left=0;//ans是最后答案,cnt统计当前最长值,temp表示可以挪走的数量,left表示该种颜色的最左边界        for(int i=1;i<n;i++){            if(a[i].color==a[i-1].color){//颜色相同的时候                cnt++;//这个算入                temp-=a[i].pos-a[i-1].pos-1;//清除掉中间的方块(清除的个数易知为pos之差-1)                while(temp<0){//如果temp已经不够了                    cnt--;//最左边算入的去掉                    temp+=a[left+1].pos-a[left].pos-1;//加上一部分                    left++;//左边界向右挪                }                ans=max(ans,cnt);//更新最大值            }            else {//颜色不一样就数据重置                left=i;                temp=k;                cnt=1;            }        }        cout<<ans<<endl;    }    return 0;}
0 0
原创粉丝点击