我是谁我在哪这个博客是谁的
luogu P1631 序列合并
怎么讲。。这个题好多解法,稍微整合一下。
题目描述
有两个长度都是N的序列A和B,在A和B中各取一个数相加可以得到(N^2)个和,求这(N^2)个和中最小的(N)个。
输入格式
第一行一个正整数N;
第二行N个整数(A_i), 满足(A_ile A_{i+1})且(A_ile 10^9);
第三行N个整数(B_i), 满足(B_ile B_{i+1})且(B_ile 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;
烦死了就这样吧晚安