CodeForces 1077D Cutting Out(二分)
题意:给你一列数,然后每次删除固定的数,问你最多删几次,打印每次删除那些数
思路:一眼看过去,这个数据范围,应该是二分,但是怎么二分check确一直没想好。其实还是忽略了二分只需要检查就好,虽然一直告诉自己这句话,但是还是没什么反应,这个题对于你枚举的x,用桶标记以后直接累加就好了,自己真是*
代码:
#include <bits/stdc++.h> using namespace std; typedef long long LL; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=1e6+7; int a[maxn]; int cnt[maxn]; int n,k; bool check(int x) { LL res=0; for(int i=1;i<maxn-5;i++){ res+=cnt[i]/x; if(res>=k)return true; } return false; } void solve(int x) { int res=0; for(int i=1;i<maxn-5;i++){ int as=cnt[i]/x; if(as){ int j=res+1; for(;j<=min(res+as,k);j++){ printf("%d ",i); if(j==min(res+as,k)){ res=j;break; } } if(res==k){ puts(""); return ; } } } } int main() { n=read();k=read(); for(int i=1;i<=n;i++)a[i]=read(),cnt[a[i]]++; int L=1,R=2e5+7; int ans; while(L<=R){ int mid=(L+R)>>1; if(check(mid)){ L=mid+1; ans=mid; } else R=mid-1; } solve(ans); return 0; }