zoukankan      html  css  js  c++  java
  • P6033 合并果子 加强版

    题目传送门

    思路

    其实我是在知道这道题要用单调队列做的前提下做的。

    不过那也没什么关系,zhizhang的我还是调了一万年才调出来,然而最后一个点还(TLE)了。心态很炸裂,看了眼题解才发现,不能用(sort),改成桶排就(A)了。

    思路非常简单,搞两个队列,一个用来存储初始的序列,而另一个用来存储每次合并之后的果子。很显然,两个队列都是单调递增的,所以每次只需要判断每个队列的前两个元素之和和分别取出队首的和哪个小就行了。这么简单的思路,实现和调试却花费了我一个小时。因为它要做到取出队列里第二个元素,而且还要分三种情况来还原和弹出,反正很恶心,写了一百多行,一交还(T)了。发现是(sort)时间复杂度炸了,还好不是算法错了。结果题解四五十行就(A)了,发现是我单调队列写麻烦了,就记录一下我冗长的代码吧。

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<cstdlib>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
    	ll x=0,f=1;char ch=getchar();
    	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    queue<ll> q1;
    queue<ll> q2;
    ll n,ans,x1,x2,y,y2,tot,sum1,sum2,sum3,inf=10000000000000;
    bool f1,f2,f3;
    ll a[10000005],sum[1000005];
    inline void first(){
    	ans+=sum1;
    	q1.pop();
    	x1=inf;
    	x2=inf;
    	q2.push(sum1);
    	if(!q1.empty()){
    		x1=q1.front();
    		q1.pop();
    	}
    	if(!q1.empty()){
    		x2=q1.front();
    	}
    	if(y==inf){
    		y=sum1;
    		q2.pop();
    		return;
    	}
    	else if(y2==inf){
    		y2=sum1;
    	}
    }
    inline void second(){
    	ans+=sum2;
    	q2.push(sum2);
    	x1=inf;
    	y=inf;
    	x2=inf;
    	y2=inf;
    	if(!q1.empty()){
    		x1=q1.front();
    		q1.pop();
    	}
    	if(!q1.empty()){
    		x2=q1.front();
    	}
    	if(!q2.empty()){
    		y=q2.front();
    		q2.pop();
    	}
    	if(!q2.empty()){
    		y2=q2.front();
    	}
    }
    inline void third(){
    	ans+=sum3;
    	q2.push(sum3);
    	q2.pop();
    	y=inf;
    	y2=inf;
    	if(!q2.empty()){
    		y=q2.front();
    		q2.pop();
    	}
    	if(!q2.empty()){
    		y2=q2.front();
    	}	
    }
    inline void qpop(){
    	sum1=x1+x2,sum2=x1+y,sum3=y+y2;
    	f1=0,f2=0,f3=0;
    	if(sum1>inf){
    		f1=1;
    	}
    	if(sum2>inf){
    		f2=1;
    	}
    	if(sum3>inf){
    		f3=1;
    	}
    	if(f2==1&&f1==1){
    		third();
    		return;
    	}
    	if(f2==1&&f3==1){
    		first();
    		return;
    	}
    	if(f1==1&&f3==1){
    		second();
    		return;
    	}
    	if(f1==1){
    		if(sum2<=sum3){
    			second();
    			return;
    		}
    		else{
    			third();
    			return;
    		}
    	}
    	if(f2==1){
    		if(sum1<=sum3){
    			first();
    			return;
    		}
    		else{
    			third();
    			return;
    		}
    	}
    	if(f3==1){
    		if(sum1<=sum2){
    			first();
    			return;
    		}
    		else{
    			second();
    			return;
    		}
    	}
    	if(f1!=1&&f2!=1&&f3!=1){
    		if(sum1<=sum2&&sum1<=sum3){
    			first();
    			return;
    		}
    		else if(sum2<=sum1&&sum2<=sum3){
    			second();
    			return;
    		}
    		else if(sum3<=sum1&&sum3<=sum2){
    			third();
    			return;
    		}
    	}
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<=n;i++){
    		a[i]=read();
    		sum[a[i]]++;
    	}
    	for(ll i=1;i<=100000;i++){
    		while(sum[i]>0){
    			sum[i]--;
    			q1.push(i);
    		}
    	}
    	x1=inf,x2=inf,y=inf,y2=inf; 
    	if(!q1.empty()){
    		x1=q1.front();
    		q1.pop();
    	}
    	if(!q1.empty()){
    		x2=q1.front();
    	}
    	if(!q2.empty()){
    		y=q2.front();
    		q2.pop();
    	}
    	if(!q2.empty()){
    		y2=q2.front();
    	}
    	while(tot<n-1){
    		qpop();
    		tot++;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    

    吐了,不想写注释了,看到就恶心

  • 相关阅读:
    Ubuntu 14.04 FTP服务器--vsftpd的安装和配置
    Python IDE专用编辑器PyCharm下载及配置安装过程(Ubuntu环境)
    Ubuntu Server14.04 32位安装odoo8.0简单方法
    js打印出对象的方法
    odoo中pos模块由于删除partner导致发生(你试图访问的单据已经删除)错误的解决方法
    django的安装和搭建
    mongodb入门
    js数组的操作
    mongodb的优缺点
    Spring动态切换多数据源解决方案
  • 原文地址:https://www.cnblogs.com/57xmz/p/13695374.html
Copyright © 2011-2022 走看看