用的贪心,40分,后六点MLE,求助
查看原帖
用的贪心,40分,后六点MLE,求助
325404
Boar楼主2022/7/26 13:38
#include<bits/stdc++.h>
using namespace std;
typedef int u;
u getmp(u b[],u l,u r){
	u mp=l,o=b[l];
	for(u i=l;i<=r;i++) if(b[i]<o) mp=i,o=b[i];
	return mp;
}//取数组在[l,r]上最小元素的下标
int main(){
	u n;
	scanf("%d",&n);
	u a[n],p=0,q;
	for(u i=0;i<n;i++) scanf("%d",a+i);
	sort(a,a+n);
	q=a[0],a[0]=0;
	for(u i=1;i<n;i++){
		if(a[i]==q+1) q=a[i],p++;
		else if(a[i]>q+1) q=a[i],p+=2;
		a[i]=p;
	}//离散化,例如原数据{1,3,4,7}将变为{0,2,3,5}
    bool m[p+1][n];//第一个下标代表当前处理的数字的大小(最大为p),第二个下标代表分组的序号(最多分n组),m[a[i]][j]代表数a[i]是否在第j组,是则1
	u r[n]; //r[i]代表第i组的人数
	memset(m,0,sizeof(m));
	memset(r,0,sizeof(r));
	u ar,al=0,mp;
	m[0][0]=1,r[0]=1;
	for(q=1;a[q]==a[q-1];q++)
    		m[0][q]=1,r[q]=1;//先处理离散化后为0的数(最小的数先占位)
	ar=q;//al,ar代表比当前正在处理的数小一的数已经占位的组的编号的下界和上界
   //q代表已经分出的组数
	for(u i=q;i<n;i++){//接着处理离散化后不为0的数
		bool h=0;//h代表在已经分了的组中是否能放入当前正在处理的数(a[i]),是则1
		for(u j=0;j<q;j++)//逐个检查已经分好的组(已经有人的组)
			if(m[a[i]-1][j]&&!m[a[i]][j]){
				if(h) al++;
				else h=1,ar=al=j;
			}//由此确定可以将当前正在处理的数(a[i])放入的组的范围
		if(h){
			mp=getmp(r,al,ar);
			r[mp]++,m[a[i]][mp]=1;
		}//如果已分好的组中有可以放入的组,那么就把a[i]放入其中最少的那一组
		else m[a[i]][q]=1,r[q]++,q++;//如果已有的组都不行,则新加一组
	}
	cout<<r[getmp(r,0,q-1)];//全部放完后输出最少的那一组的人数
    return 0;
}
2022/7/26 13:38
加载中...