#luogu整理 P1631 序列合并

我是谁我在哪这个博客是谁的

luogu P1631 序列合并

怎么讲。。这个题好多解法,稍微整合一下。

题目描述

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

输入格式

第一行一个正整数N;

第二行N个整数\(A_i\), 满足\(A_i\le A_{i+1}\)\(A_i\le 10^9\);

第三行N个整数\(B_i\), 满足\(B_i\le B_{i+1}\)\(B_i\le 10^9\).

输出格式

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

样例

\(in\)

3
2 6 6
1 4 8

\(out\)

3 6 7

思路

抄的思路

因为只用挑选n个最小的数字,所以我们其实在枚举i和j的同时,加一个判断i * j <= n就可以保证答案的正确性和时间复杂度。前面这个式子的证明大概就是一句话:

  • 因为要选前n个最小的数,且若有\(x > i,y > j\),则一定有a[i] + b[j] < a[x] +b[y],所以一定有最小的n个数在i * j <= n这个范围里面。

\(Code\)

    cin >> n;
    for(int i = 1;i <= n; i++) cin >> a[i];
    for(int i = 1;i <= n; i++) cin >> b[i];
    sort(a+1,a+1+n);
    sort(b+1,b+1+n);
    int tot = 0;
    for(int i = 1;i <= n; i++)
        for(int j = 1;j <= n && i * j <= n; j++){
            ans[++tot] = a[i] + b[j];
        }
    sort(ans+1,ans+1+tot);
    for(int i = 1;i <= n; i++) cout << ans[i] << ' ';
    cout << endl;

烦死了就这样吧晚安

posted @ 2020-06-12 17:28  CYC的幸福生活  阅读(113)  评论(0编辑  收藏  举报