您的位置:首页 > 其它

Consecutive Blocks (ZOJ3970)

2016-03-22 19:53 387 查看
给出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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: