• 洛谷 P1631 序列合并


     题目传送门

    解题思路:

    首先,把A和B两个序列分别从小到大排序,变成两个有序队列。这样,从A和B中各任取一个数相加得到N2个和,可以把这些和看成形成了n个有序表/队列:

    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个有序队列进行合并排序:

    首先,将这N个队列中的第一个元素放入一个堆中;

    然后;每次取出堆中的最小值。若这个最小值来自于第k个队列,那么,就将第k个队列的下一个元素放入堆中。

    时间复杂度:O(NlogN)。

    //以上转载自:https://www.luogu.org/blog/user23845/solution-p1631

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<algorithm>
     5 
     6 using namespace std;
     7 
     8 struct kkk {
     9     int v,xb,js;
    10 }p[100001];
    11 int n,a[100001],b[100001];
    12 priority_queue<kkk> l;
    13 
    14 bool operator < (kkk a,kkk b){
    15     return a.v > b.v;
    16 }
    17 
    18 void shu_ru() {
    19     scanf("%d",&n);
    20     for(int i = 1;i <= n; i++){
    21         scanf("%d",&a[i]);
    22         p[i].xb = i;
    23         p[i].js = 1;
    24     }    
    25     for(int i = 1;i <= n; i++)
    26         scanf("%d",&b[i]);
    27     sort(a+1,a+1+n);
    28     sort(b+1,b+n+1);
    29 }
    30 
    31 int main() {
    32     shu_ru();
    33     for(int i = 1;i <= n; i++) {
    34         p[i].v = b[1] + a[i];
    35         l.push(p[i]);
    36     }
    37     for(int i = 1;i <= n; i++) {
    38         printf("%d ",l.top().v);
    39         kkk u;
    40         u.xb = l.top().xb;
    41         u.js = l.top().js + 1;
    42         l.pop();
    43         u.v = a[u.xb] + b[u.js];
    44         l.push(u);
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    cast() 函数进行类型转换
    '+' 拼接字符串引起的小事故
    shell统计ip访问情况并分析访问日志
    Windows 环境上域名配置
    WebApi中Route的作用
    Postman测试WebApi使用总结
    C# VS2017新建WepApi
    C# 反射总结
    winform--同一个项目窗体复制
    winform TextBox设置透明
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11241157.html
Copyright © 2020-2023  润新知