Consecutive Blocks (ZOJ3970)

给出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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值