• P1631 序列合并


    题目来源:洛谷

    题目描述

    有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到N^2个和,求这N^2个和中最小的N个。

    输入输出格式

    输入格式:

    第一行一个正整数N;

    第二行N个整数AiAi+110^9Ai109;

    第三行N个整数BiBi+110^9Bi109.

    【数据规模】

    对于50%的数据中,满足1<=N<=1000;

    对于100%的数据中,满足1<=N<=100000。

    输出格式:

    输出仅一行,包含N个整数,从小到大输出这N个最小的和,相邻数字之间用空格隔开。

    输入输出样例

    输入样例#1:
    3
    2 6 6
    1 4 8
    输出样例#1:
    3 6 7

    解析:

    这题数学上讲不难,很容易想到解法根据题意,对于有序数列a和b,其最小和一定是a1+b1,次小和为min(a2+b1,b2+a1),如果次小和为a1+b2,那么第三小和就是min(a2+b1,a+b3,a2+b2),至于原因,我们知道an肯定比an-1大放到这里,因为次小和是a1+b2,所以,a2+b1的值是肯定比它要大的,而从它衍生出来的这两个值,就分别是an+1+bn和an+bn+1了因为他们是仅比a1+b2小的最大值。以此类推,我们得到可以得出本题的朴素解法。

    优化是判重,由于(x,y+1)和(x+1,y)二者拓展出的解都覆盖了(x+1,y+1),我们只需要一个就好了,这样就可以的出遍历的唯一路径了。扎心的是,本蒟蒻STL的使用及其不成熟,重载运算符也不大会,而且其实貌似也不用自定义结构体的,但是我不会用优先队列,依葫芦画瓢写了个代码出来,思路虽然有,码不出来就很尴尬。。。其一,我们可以用pair将两个序列绑定,并用map判重;其二,我们可以只将某个数值的序号存入堆,取出时放到数组下标中加和就行了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<ctime>
     6 #include<cstdlib>
     7 #include<algorithm>
     8 #include<queue>
     9 #include<set>
    10 #include<map>
    11 #define N 100010
    12 using namespace std;
    13 typedef pair<int,int> pp;
    14 map<pp,bool> p;
    15 int a[N],b[N];
    16 struct node{
    17     int i,j;
    18     bool operator <(const node &t) const{
    19         if(a[i]+b[j]<a[t.i]+b[t.j]) return false;
    20         return true;
    21     }
    22     node(int x,int y){
    23         i=x,j=y;
    24     }
    25 };
    26 priority_queue<node> q;
    27 int main()
    28 {
    29     int n;
    30     scanf("%d",&n);
    31     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    32     for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    33     q.push(node(1,1));
    34     
    35     for(int i=1;i<=n;i++)
    36     {
    37         while(p[make_pair(q.top().i,q.top().j)]) q.pop();
    38         int xx=q.top().i;
    39         int yy=q.top().j;
    40         printf("%d ",a[xx]+b[yy]);
    41         p[make_pair(q.top().i,q.top().j)]=true;
    42         q.push(node(xx,yy+1));
    43         q.push(node(xx+1,yy));
    44     }
    45     return 0;
    46 }

    2019-05-18 22:23:23



  • 相关阅读:
    微服务-SpringCloud学习系列(二):注册中心Eureka
    Spring Security系列(一)简介
    程序人生(一)--习惯与性格
    JavaEE系列(一)--Filter技术
    JavaEE系列(一)--Servlet技术
    微服务-SpringCloud学习系列(一):认识微服务
    mongoDB安装
    php遍历目录下的文件
    mysql创建视图
    ssh 安全策略
  • 原文地址:https://www.cnblogs.com/DarkValkyrie/p/10887420.html
Copyright © 2020-2023  润新知