K Smallest Sums UVA - 11997

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
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;
	}
}

你可能感兴趣的:(头秃宝典)