D - K Smallest Sums

D - K Smallest Sums


You’re given k arrays, each array has k integers. There are kk ways to pick exactly one element in each array and calculate the sum of the integers. Your task is to find the k smallest sums among them.
Input There will be several test cases. The first line of each case contains an integer k (2 ≤ k ≤ 750). Each of the following k lines contains k positive integers in each array. Each of these integers does not exceed 1,000,000. The input is terminated by end-of-file (EOF).
Output
For each test case, print the k smallest sums, in ascending order.
Sample Input
3 1 8 5 9 2 5 10 7 6 2 1 1 1 2
Sample Output
9 10 12 2 2

这道题网上代码都是大同小异了,我就不仔细解析了,主要通过这个题巩固下优先队列operator<  的重载,其实这个题重载不考虑多个判断也可以过,但是我感觉我太严谨。

那么重载< , 要记住一句话,判断真的话,就把真的东西放在后面,即最后输出。

例如,return a.num < b.num; 如果真,即a.num 小,那就把a放在后面。

如果判断的不是num这种具体的数,而是别的,例如,是否等于某个边界,这时候就不太好理解, 这也就是我写这个的原因,

利用上边这句话就可以理解这个问题。


#include<iostream>
using namespace std;
#include<cstdio>
#include<algorithm>
#include<math.h>
#include<queue>
#include<string.h>
#define inf 0x3f3f3f3f
int n;
int A[764];
int B[765];
struct spe
{
	int total,index;
	friend bool operator<( spe a, spe b )
	{
		if( a.total != b.total )
			return a.total > b.total;
		if( a.index != n && b.index != n )
			return a.total+A[a.index+1]-A[a.index] > b.total + B[b.index+1]-B[b.index];
		return (a.index == n);
	}
};
void merge()
{
	int c[755];
	priority_queue<spe> q;
	for( int i = 1 ; i <= n ; i++ )
	{
		spe temp;	temp.index = 1;	temp.total = A[1]+B[i];
		q.push(temp);
	}
	for( int i = 1 ; i <= n ; i++ )
	{
		spe t = q.top();	q.pop();
		c[i] = t.total;
		if( t.index != n )
		{
			spe temp;
			temp.index = t.index+1;
			temp.total = t.total + A[t.index+1]-A[t.index];
			q.push(temp);
		}
	}
	for( int i = 1 ; i <= n ; i++ )
		A[i] = c[i];
}
int main()
{
	while( scanf("%d",&n) == 1 && n )
	{
		for( int i = 1 ; i <= n ; i++ )
			scanf("%d",&A[i]);
		sort(A+1,A+1+n);
		for( int i = 2 ; i <= n ; i++ )
		{
			for( int j = 1 ; j <= n ; j++ )
				scanf("%d",&B[j]);
			sort(B+1,B+1+n);
			merge();
		}
		printf("%d",A[1]);
		for( int i = 2 ; i <= n ; i++ )
			printf(" %d",A[i]);
		printf("\n");
	}
	return 0;
}
/*



*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值