首页 > 代码库 > ZOJ3790_Consecutive Blocks
ZOJ3790_Consecutive Blocks
给出一个数组,最多可以删除k个数,问能够获得的最长的一个数字连续段为多少?
把所有相同的数字都提取出来,保存取得每个数字需要删除的数字,然后二分枚举就可以了。
召唤代码君:
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#define maxn 500200using namespace std;int a[maxn],b[maxn],first[maxn],next[maxn];int Q[maxn],top,f[maxn];bool vis[maxn];int n,k,N,ans;void go(int cur){ vis[cur]=true; if (next[cur]!=-1){ go(next[cur]); Q[top++]=cur-next[cur]-1; } else Q[top++]=0;}int main(){ while (scanf("%d%d",&n,&k)!=EOF){ for (int i=0; i<n; i++){ scanf("%d",&a[i]); b[i]=a[i]; } sort(b,b+n); N=unique(b,b+n)-b; for (int i=0; i<n; i++) a[i]=lower_bound(b,b+N,a[i])-b+1; memset(first,-1,sizeof(int)*(n+3)); for (int i=0; i<n; i++) next[i]=first[a[i]],first[a[i]]=i; memset(vis,false,sizeof(bool)*(n+2)); ans=0; for (int i=n-1; i>=0; i--) if (!vis[i]){ top=0; go(i); for (int j=1; j<top; j++) Q[j]+=Q[j-1]; for (int pos=0; pos<top; pos++){ if (Q[top-1]-Q[pos]<=k){ ans=max(ans,top-pos); break; } int l=pos,r=top-1,mid; while (l<r){ mid=(l+r+1)/2; if (Q[mid]-Q[pos]>k) r=mid-1; else l=mid; } ans=max(ans,l-pos+1); } } printf("%d\n",ans); } return 0;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。