1. 程式人生 > >codevs 1245 最小的N個和

codevs 1245 最小的N個和

pan width 長度 spa dev char getc 初始 turn

技術分享 題目描述 Description

有兩個長度為 N 的序列 A 和 B,在 A 和 B 中各任取一個數可以得到 N^2 個和,求這N^2 個和中最小的 N個。

輸入描述 Input Description

第一行輸入一個正整數N;第二行N個整數Ai 且Ai≤10^9;第三行N個整數Bi,
且Bi≤10^9

輸出描述 Output Description

輸出僅一行,包含 n 個整數,從小到大輸出這 N個最小的和,相鄰數字之間用
空格隔開。

樣例輸入 Sample Input

5

1 3 2 4 5
6 3 4 1 7

樣例輸出 Sample Output

2 3 4 4 5

***************************************************************

方法::

暴力枚舉即可

可以推出,將兩個初始數列排序後,對於a數列中第i個,與他配對的只需要枚舉到b數列的第n/i個即可

原因是::

若第i個再最後輸出的序列中最多包含的尤其相加的結果的個數是x個,則a【】前面的所有元素所能配出比 第i個所配出的個數都多或相等(舉個例子)

A---------1 3 3 5 9 11

B---------1 2 3 4 5 6

假如我們找到了a的第三個元素,我們只需要和b的前兩個配對即可,因為a【1】,a【2】與b的前兩個的配對不可能大於第三個元素的配對,這樣我們就已經找出了至少6個最小的,

滿足題目要求了有木有。

這樣我們用數組記錄下找出的對的值,最後排一遍序就行了

代碼::

#include<cstdio>
#include<algorithm>
#define maxn 100001
using namespace std;
int a[maxn];
int b[maxn];
int c[maxn*10];
int cha[maxn];
int top = 0;
int n;
int read()
{
    int num = 0;
    char c = getchar();
    int f = 1;
    while(c < 0||c > 
9) { if(c == -)f = -1; c = getchar(); } while(c >= 0 && c <= 9) { num *= 10; num += c - 0; c = getchar(); } return num * f; } int main() { n = read(); for(int i = 1;i <= n; i ++) { a[i] = read(); } for(int i = 1;i <= n; i ++) { b[i] = read(); } sort(a + 1,a + n + 1); sort(b + 1,b + n + 1); for(int i = 1;i <= n;i ++) { int zz = n / i ; //if( i > 10 )zz = min(zz,10); for(int j = 1;j <= zz;j ++) { cha[++ top] = a[i] + b[j]; } } sort(cha + 1,cha + top + 1); for(int i = 1; i <= n; i ++) { printf("%d ",cha[i]); } return 0; }

codevs 1245 最小的N個和