zoukankan      html  css  js  c++  java
  • P1631 序列合并

    P1631 序列合并

    题目描述
    有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个。
    对于100%的数据中,满足1<=N<=100000。

    Solution

    数据范围表示 (N^{2}) 要命
    然而有一个想法, 要找出这 (N^{2}) 个数的大致大小情况, 从这里入手

    对两序列排序
    我们把这 (N^{2}) 个数列出来, 可以发现, 以下式子成递增序列
    一行中前一个恒大于等于后一个

    [a_{1} + b_{1}, a_{1} + b_{2}, ..., a_{1} + b_{N} ]

    [a_{2} + b_{1}, a_{2} + b_{2}, ..., a_{2} + b_{N} ]

    [... ]

    [a_{N} + b_{1}, a_{N} + b_{2}, ..., a_{N} + b_{N} ]

    所以我们先把每一行第一个放入小根堆中, 每次取出堆顶输出, 同时将此行下一个数丢进堆中, 重复 (N) 次即可, 复杂度 (O(Nlog N))

    Code

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #include<queue>
    #define LL long long
    using namespace std;
    int RD(){
        int out = 0,flag = 1;char c = getchar();
        while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
        while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
        return flag * out;
        }
    const int maxn = 200019;
    int num;
    int a[maxn], b[maxn];
    struct Node{
    	int val, i, j;
    	bool operator < (const Node &a)const{
    		return val < a.val;
    		}
    	};
    priority_queue<Node>Q;
    int main(){
    	num = RD();
    	for(int i = 1;i <= num;i++)a[i] = RD();
    	for(int i = 1;i <= num;i++)b[i] = RD();
    	sort(a + 1, a + 1 + num), sort(b + 1, b + 1 + num);
    	for(int i = 1;i <= num;i++)Q.push((Node){-(a[i] + b[1]), i, 1});
    	while(num--){
    		Node now = Q.top();Q.pop();
    		int i = now.i, j = now.j;
    		printf("%d ", -now.val);
    		Q.push((Node){-(a[i] + b[j + 1]), i, j + 1});
    		}
    	puts("");
    	return 0;
    	}
    
  • 相关阅读:
    .NET的DTO映射工具AutoMapper
    使用TeamCity对项目进行可持续集成管理
    SpecFlow
    重构--改善既有代码的设计
    EntityFramework 7 开发纪录
    Solr索引
    DDD分层架构之值对象(层超类型篇)
    C#异步Socket示例
    Cnblogs API
    白鸦三次创业反思:公司遇问题 怎么走都对(转)
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9745664.html
Copyright © 2011-2022 走看看