终于不是水题了,第一版想的太简单了,很多情况没考虑到,关键就是当遇到重复的部分时该怎么分组
//第一次尝试-失败:遇到重复就断掉重开一个组,显然只满足部分情况
int main() {
int n;
cin>>n;
ll a[n+10];
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n);
int min=100000,p=1;
for(int i=1;i<n;i++) {
if(a[i]==a[i-1]+1) p++;
else {min=p<min?p:min;p=1;}
if(i==n-1) min=p<min?p:min;
}
cout<<min;
return 0;
}
题解有个思路,和以前我们玩过的“蜘蛛纸牌”有点类似,每张牌我们放到上一张比他小1的那个组,优先放牌数小的那个组,没有可以放的组就重开一个
#define Init 100005
struct group{
ll next;
int len=0;
}f[Init];
bool cmp(group x,group y) {
return x.len<y.len;
}
int main() {
ll a[Init];
int n,p=0;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n);
for(int i=0;i<n;i++) {
bool flag=1;//=1表示没找到组织
for(int j=p;j>=0;j--)//找到符合条件当前的组数最小的组,从右往左
if(a[i]==f[j].next) {
f[j].next++;
f[j].len++;
flag=0;//表明找到了,不用开新开一个组
break;
}
if(flag) {
f[p].next=a[i]+1;
f[p++].len++;
}
}
sort(f,f+p,cmp);
cout<<f[0].len;
return 0;
}