zoukankan      html  css  js  c++  java
  • 【NOIP2017】蚯蚓

    有n只蚯蚓,每次选取一条最长的,按比例切成两半
    然后其它没有被切的全部增加一个长度q
    问每次切的是哪条蚯蚓,最后所有蚯蚓的长度是多少
    

    朴素的暴力想法:
    类似于合并石子,使用一个堆来储存长度,每次取出堆顶切成两半
    其它蚯蚓增加长度=这两半减少长度
    输出的时候加上总增加长度即可

    但考虑一下,需要优先队列来储存吗?
    可以证明,无论哪种情况,先切的蚯蚓两半的长度一定大于后切的蚯蚓两半的长度
    自带单调性啊

    所以我们直接开三个数组,分别存原长,切了后第一段长度,切了后第二段长度
    每次取出三个数组第一个元素的最大值操作即可

    这三个数组不是堆,因为操作过程本身就保证了单调性

    代码:

    #include<bits/stdc++.h>
    #define N 10000005
    using namespace std;
    
    int n,m,q,u,v,t,x,y;
    int a[N],b[N],c[N];
    int head=1,tail,head1=1,head2=1,tail1=0,tail2=0;
    int lst[N*10],cnt;
    int sigma;
    
    template<class T>inline void read(T &res)
    {
    	char c;T flag=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }
    
    inline bool cmp(int a,int b) {return a>b;}
    
    int main()
    {
    //	freopen("testdata.in","r",stdin);
    //	freopen("testdata.txt","w",stdout);
    	read(n);read(m);read(q);
    	read(u);read(v);read(t);
    	double p=(double)u/v;
    	
    	for(register int i=1;i<=n;++i) read(a[i]);
    	tail=n;
    	sort(a+1,a+n+1,cmp);
    	int top;
    	for(register int i=1;i<=m;++i)
    	{
    		if(head>tail)
    		{
    			if(b[head1]>c[head2]) top=b[head1++];
    			else top=c[head2++];
    		}
    		else if(a[head]>=b[head1]&&a[head]>=c[head2]) top=a[head++];
    		else if(b[head1]>=c[head2]&&a[head]<=b[head1]) top=b[head1++];
    		else top=c[head2++];
    		
    		top+=sigma;
    		x=floor(p*(double)top),y=top-x;
    		sigma+=q;
    		b[++tail1]=x-sigma;
    		c[++tail2]=y-sigma;
    		if(i%t==0) printf("%d ",top);
    	}
    	puts("");
    	for(register int i=head;i<=tail;++i) lst[++cnt]=a[i];
    	for(register int i=head1;i<=tail1;++i) lst[++cnt]=b[i];
    	for(register int i=head2;i<=tail2;++i) lst[++cnt]=c[i];
    	sort(lst+1,lst+cnt+1,cmp);
    //	for(register int i=1;i<=cnt;++i) cout<<lst[i]+sigma<<" ";
    	int now=0;
    	for(register int i=1;i<=cnt;++i)
    	{
    		now++;
    		if(i%t==0) printf("%d ",lst[now]+sigma);
    	}
    	return 0;
    }
    
  • 相关阅读:
    字符串中的不可见字符应该如何清除?
    字符/字段数据的合并
    分割字符串的应用
    几种分割字符串实现方法的比较
    linux的一些文件基本命令
    centos7安装es6.4.0
    Sql 语句中 IN 和 EXISTS 的区别及应用
    Springboot通过redisTemplate实现发布订阅
    代理模式
    单例模式的多种实现方法
  • 原文地址:https://www.cnblogs.com/tqr06/p/11831907.html
Copyright © 2011-2022 走看看