#队列#洛谷 6033 合并果子 加强版

题目


分析

首先必须做到\(O(n)\)的时间复杂度,
第一次排序考虑使用桶排,由于合并后的果子也是升序的,
考虑用两个队列分别装下原果子和合并后的果子,用两个指针判断一下即可


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=100011,M=20000011; typedef long long lll;
int CNT[N],mn[2],n; long long a[M],ans;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
signed main(){
	for (n=iut();n;--n) ++CNT[iut()];
	for (rr int i=1;i<N;++i)
	for (rr int j=1;j<=CNT[i];++j)
	    a[++n]=i;
	rr int l=1,r=n+1,head=n;
	for (rr int i=1;i<n;++i){
		for (rr int j=0;j<2;++j){
			if ((a[l]<=a[r]&&l<=n)||!a[r]) mn[j]=l++;
			    else if (r<=head) mn[j]=r++; else mn[j]=l++;
		}
		ans+=a[++head]=a[mn[0]]+a[mn[1]];
	}
	return !printf("%lld",ans);
}
posted @ 2020-10-15 11:24  lemondinosaur  阅读(114)  评论(0编辑  收藏  举报