标签:cnt return int Max tot cf1121d maxn 尺取
尺取,写起来有点麻烦
枚举左端点,然后找到右端点,,使得区间[l,r]里各种颜色花朵的数量满足b数组中各种花朵的数量,然后再judge区间[l,r]截取出后能否可以供剩下的n-1个人做花环
/* 给定序列A,分成n段,每段k个, 然后删掉A中的一些,但任要能组成n段,使得A中的一段包含序列B中的所有元素 如果可以输出删掉的元素,否则输出-1 */ #include<bits/stdc++.h> using namespace std; #define maxn 500005 int m,k,n,s,a[maxn],b[maxn],c[maxn]; int tot[maxn],cnt[maxn];//tot[i]表示第i种颜色需要的数量 int l,r,sum,Max,all; int judge(int l,int r){//判断除去l,r是否可行 int tmp1=l-1,tmp2=m-r; if(tmp1/k+tmp2/k+1>=n)return 1; return 0; } void add(int i){ if(cnt[a[i]]==0)return; tot[a[i]]++; if(tot[a[i]]==cnt[a[i]])sum++; } void del(int i){ if(cnt[a[i]]==0)return; tot[a[i]]--; if(tot[a[i]]==cnt[a[i]]-1)sum--; } int main(){ cin>>m>>k>>n>>s; for(int i=1;i<=m;i++)cin>>a[i],Max=max(Max,a[i]); for(int i=1;i<=s;i++)cin>>b[i],Max=max(Max,b[i]); for(int i=1;i<=s;i++)cnt[b[i]]++; l=1,r=k;sum=0; for(int i=1;i<=Max;i++) if(cnt[i]!=0)all++; for(int i=l;i<=k;i++) add(i); while(1){ if(sum==all){ if(judge(l,r)){//可行 vector<int>v; v.clear(); int tmp=r-l+1; for(int i=l;i<=r;i++){ if(cnt[a[i]]>0 || tmp==k) cnt[a[i]]--; else v.push_back(i),tmp--; } printf("%d\n",v.size()); for(int i=0;i<v.size();i++) printf("%d ",v[i]); return 0; } del(l);l++; } while(sum<all || l+k-1>r){ r++; if(r>m)break; add(r); } if(r>m)break; } puts("-1"); }
标签:cnt,return,int,Max,tot,cf1121d,maxn,尺取 来源: https://www.cnblogs.com/zsben991126/p/10470567.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。