• Sequence


    POJ

    多组数据,给定(m)个长度为(n)的序列,从每个序列中取出一个数相加可以得到一个和,输出前n小的和.(n<=2000,m<=100).

    分析:某场考试的弱化版,可以在(Tmnlog_n)的时间复杂度内做.考虑(m=2)时的情况,把两个序列都从小到大排序,先把(a[i]+b[1])全都丢入小根堆中,然后每次取出堆顶(a[i]+b[j])记录答案,同时把(a[i]+b[j+1])丢入堆中.

    (m>2)时,重复做(m-1)次上述操作即可.具体来说,每次得到的答案当做一个新的(a)序列,然后与读入的(b)序列进行上述操作.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=2005;
    int n,m,a[N],b[N],c[N];
    struct node{
    	int x,y,val;
    	bool operator <(const node &x)const{
    		return val>x.val;
    	}
    }temp;
    inline void solve(){
    	priority_queue<node>q;
    	for(int i=1;i<=n;++i){
    		temp.x=i;temp.y=1;temp.val=a[i]+b[1];
    		q.push(temp);
    	}
    	for(int i=1;i<=n;++i){
    		temp=q.top();q.pop();
    		c[i]=temp.val;
    		if(temp.y<n){
    			++temp.y;temp.val=a[temp.x]+b[temp.y];
    			q.push(temp);
    		}
    	}
    	for(int i=1;i<=n;++i)a[i]=c[i];
    }
    int main(){
    	int T=read();
    	while(T--){
    		m=read(),n=read();
    		for(int i=1;i<=n;++i)a[i]=read();
    		sort(a+1,a+n+1);
    		for(int i=2;i<=m;++i){
    			for(int j=1;j<=n;++j)b[j]=read();
    			sort(b+1,b+n+1);solve();
    		}
    		for(int i=1;i<n;++i)printf("%d ",a[i]);
    		printf("%d
    ",a[n]);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    数字形式转换
    货币转换
    温度转换
    volatile 的可见性,禁止指令重排序,无法保证原子性的理解
    mysql索引的结构的分析
    史上最详细的ORACLE19c安装说明
    Solaris 修改联网代理的设置
    Oracle Drop表并未直接删除 drop table xx purge
    oracle自定义函数创建函数索引
    连线法合并两个有序链表
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11696577.html
Copyright © 2020-2023  润新知