zoukankan      html  css  js  c++  java
  • 洛谷 P6033 [NOIP2004 提高组] 合并果子 加强版(桶排序,队列)

    传送门


    解题思路

    经典题的加强版。
    根据数据范围得出需要O(n)解决这个问题。
    至少要进行一次排序,而且数字<=1e5,所以很显然可以桶排。
    然后用两个队列(注意不是优先队列),一个是存原数,一个存和。
    每次取出两个队列中前二的两个数字,然后加起来放到第二个队列的队尾即可。
    易证两个队列里面的数都满足单调性。
    手写队列会很简单,但我就用stl,于是写了死长的代码还有各种判断。
    唉,就是玩儿~

    AC代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<iomanip>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int maxn=1e5+5;
    int n,a,maxa,c[maxn];
    long long ans,a1,a2;
    queue<long long> q1,q2;
    int read(){
    	int res=0;
    	char c=getchar();
    	while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9'){
    		res=res*10+c-'0';
    		c=getchar();
    	}
    	return res;
    } 
    int main(){
    	ios::sync_with_stdio(false);
    	n=read();
    	for(int i=1;i<=n;i++) a=read(),maxa=max(maxa,a),c[a]++;
    	for(int i=1;i<=maxa;i++){
    		while(c[i]--) q1.push(i);
    	}
    	if(n==1){
    		cout<<q1.front()<<endl;
    		return 0;
    	}
    	a1=q1.front();
    	q1.pop();
    	ans+=q1.front()+a1;
    	q2.push(q1.front()+a1);
    	q1.pop();
    	while(!q1.empty()){
    		if(q1.front()>q2.front()){
    			a1=q2.front();
    			q2.pop();
    		}else{
    			a1=q1.front();
    			q1.pop();
    		}
    		if(q1.empty()){
    			a2=q2.front();
    			q2.pop();
    		}else{
    			if(q2.empty()){
    				a2=q1.front();
    				q1.pop();
    			}else{
    				if(q1.front()>q2.front()){
    					a2=q2.front();
    					q2.pop(); 
    				}else{
    					a2=q1.front();
    					q1.pop();
    				}
    			}
    		}
    		ans+=a1+a2;
    		q2.push(a1+a2);
    	}
    	while(!q2.empty()){
    		a1=q2.front();
    		q2.pop();
    		if(q2.empty()) break;
    		a2=q2.front();
    		q2.pop();
    		ans+=a1+a2;
    		q2.push(a1+a2);
    	}
    	cout<<ans;
        return 0;
    }
    
  • 相关阅读:
    [自用] 数论和组合计数类数学相关(定理&证明&板子)
    OI回忆录?
    [UOJ310] 黎明前的巧克力
    [总结] 后缀自动机学习笔记
    [总结] 动态点分治学习笔记
    [HEOI2018] 秘密袭击coat
    [51nod1355] 斐波那契的最小公倍数
    [SRM601] WinterAndSnowmen
    [总结] 二项式反演学习笔记
    [Luogu4705] 玩游戏
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15269828.html
Copyright © 2011-2022 走看看