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). The size of input file does not exceed 5MB.
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
Output for the Sample Input
9 10 12 2 2
我的思路就是先找出每队中最小的数,然后用一个数组存储每个数组中的数与该组最小数的差,然后排序该数组,最后依次把最小数之和与这些数相加。
纠结了很久,刚开始用选择排序超时了,就改用快排,提交之后WA,一直想不通是哪里错了。
后来终于想明白了,这种方法每次只变换一个数,漏掉了变换多个数的情况!
如下面这个测试案例:
4
1 2 14 16
3 4 15 16
5 9 9 100
7 10 111 112
答案应该是16 17 17 18
但该程序运行结果为:16 17 17 19
错误代码如下:
#include <stdio.h>
int a[750][750];
int count[750];
int main(void)
{
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
void quicksort(int *a,int p,int r);
int min(int *a,int k);
int k,i,j;
int minn[750];
while(scanf("%d",&k)!=EOF)
{
int sum=0,t=0;
for(i=0;i<k;i++)
{
for(j=0;j<k;j++)
scanf("%d",&a[i][j]);
minn[i]=min(a[i],k);
sum+=minn[i];
for(j=0;j<k;j++)
count[t++]=a[i][j]-minn[i];
}
quicksort(count,1,t-1);
printf("%d",sum+count[k-1]);
for(i=k;i<2*k-1;i++)
printf(" %d",sum+count[i]);
printf("\n");
}
return 0;
}
void quicksort(int *a,int p,int r)
{
int partition(int *a,int p,int r);
if(p<r)
{
int q=partition(a,p,r);
quicksort(a,p,q-1);
quicksort(a,q+1,r);
}
return ;
}
int partition(int *a,int p,int r)
{
int x=a[r];
int i=p-1,j;
for(j=p;j<r;j++)
if(a[j]<=x)
{
i++;
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
int temp=a[i+1];
a[i+1]=a[r];
a[r]=temp;
return i+1;
}
int min(int *a,int k)
{
int i;
int minnum=1000001;
for(i=0;i<k;i++)
if(a[i]<minnum)
minnum=a[i];
return minnum;
}