1. 程式人生 > >CodeForces 1077D Cutting Out(二分)

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; }