K Smallest Sums UVA - 11997
提交捷径
(蓝书题目)
题目大意:
K个整数数组 , 包含K个元素 , 在每个数组中取一个元素加起来 , 可以得到 kk个和,
求出和中最小的K个值
输入
3
1 8 5
9 2 5
10 7 6
2
1 1
1 2
输出
9 10 12
2 2
解题思路 ,既然我们需要求最小和 ,我们很容易想到对每组进行排序来方便我们找出来。光想到这一点还不够 , 我们还需要找到第二个最小和 , 这里我们使用优先队列来获得。
#include<bits/stdc++.h>
using namespace std;
int nums[755][755] , n;
struct node
{
int b , s;
// s = A[a] + A[b];
node(int b , int s) : b(b) , s (s){}
bool operator < (const node &a)const{
return s > a.s;
}
};
void merge(int *A , int *B , int *C){
//待A与B合并完后存放点为C。
priority_queue<node> q;
for(int i = 0; i < n; i ++)
{
q.push(node(0 , A[i] + B[0]));
//因为C就是A , 所以叠加在C上。猜测最小值是这些
}
for(int i = 0; i < n; i ++){
node tmp = q.top(); q.pop();
C[i] = tmp.s;
int b = tmp.b;
if(b + 1 < n) q.push(node(b + 1 , tmp.s - B[b] + B[b + 1]));
//在队列中tmp.s即A[a]+B[b]是最小值 , 那么 A[a] + B[b+1]可能就是次最小的,须方进去
}
}
int main(){
while(cin >> n){
for(int i = 0; i < n; i ++)
{
for(int j = 0; j < n; j ++)
cin >> nums[i][j];
sort(nums[i] , nums[i] + n);
}
for(int i = 1; i < n; i ++){
merge(nums[0] , nums[i] , nums[0]);
for(int i = 0; i < n; i ++){
printf("[%d] " , nums[0][i]);
}
cout << endl;
}
cout << nums[0][0];
for(int i = 1; i < n; i ++){
//两两叠加
cout << " " << nums[0][i];
}
cout << endl;
}
}