TZOJ:8525
题目大意是给定n个整数,要求连续的整数为一组,最后要求出人数最小的组的人数最大数。
题解是首先将整个a数组排升序,那么遇到相同的数字的情况就可以开新的组别,保存每个组别的最大值以及各个组别的人数大小,a数组排序就是为了让组别最大值也是升序的。
遇到当前数字a【i】就二分各个组别的最大值,如果能搜到组别最大值为a【i】-1,那么就更新那个组的最大值,并且人数+1,如果找不到就新建一个组别,使这个组别最大值为a【i】,人数为1。
关键是每次二分都要找到最后一个符合条件的值,因为最大值相同的情况下,后面的组别人数一定是比前面的组别人数少的,所以我们把符合条件的值放到后面的组别可以维护整体的平衡。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a[N],m,b[N],c[N];
int find(int l,int r,int x)
{
while(l<=r)
{
int mid=(l+r)/2;
if(b[mid]<=x)l=mid+1;
else r=mid-1;
}
return r;
}
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
m=0;
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
int t=find(1,m,a[i]-1);
if(t>=1&&t<=m&&b[t]==a[i]-1)b[t]=a[i],c[t]++;
else b[++m]=a[i],c[m]=1;
}
int Min=1e9;
for(int i=1;i<=m;i++)Min=min(Min,c[i]);
cout<<Min<<endl;
}