UVa 11997 K Smallest Sums


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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值