题目大意是:m行n列的一个数矩阵,每行抽一个数,可以同列,那么有n^m种sequence组合,在这些sequence中,找出:sequence和最小的n个sequence组合
方法:
当行数大于等于2行时候
先比较第一行和第二行的和,把较小的放在第一行,把第一行压入优先队列
行数只有1行的时候,不进行该操作,直接把第一行的数压入优先队列(否则会造成第二行是0行和第一行交换后,把0行压入优先队列,wa掉)
对接下来的第2行到第m行
先把优先队列输入到一个数组a里面,并把优先队列清空,a是从大到小的,那么接下来的遍历都是倒序遍历
排序该行,然后该行第一个数和a中所有数相加压入优先队列
对该行的第二个到第n个数每个数,和a里面每个数相加,如果比优先队列最大的元素小,那么弹出最大元素,压入该元素,比最大元素大,则break,跳到该行的下一个数
最后输出结果问题,最后一个数不要带空格,只能带回车符
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
priority_queue<int>que;
int m,n;
int num[1111][2222];
int a[2222];
int main()
{
#ifndef ONLINE_JUDGE
freopen("G:/1.txt","r",stdin);
freopen("G:/2.txt","w",stdout);
#endif
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&num[i][j]);
}
}
if(m>=2)
{
int sum1=0,sum2=0;
for(int i=1;i<=n;i++)
sum1+=num[1][i];
for(int i=1;i<=n;i++)
sum2+=num[2][i];
if(sum1>sum2)
swap(num[1],num[2]);
}
for(int i=1;i<=n;i++)
{
que.push(num[1][i]);
}
for(int i=2;i<=m;i++)
{
sort(num[i]+1,num[i]+1+n);
for(int j=1;j<=n;j++)
{
a[j]=que.top();
que.pop();
}
for(int j=1;j<=n;j++)
{
que.push(num[i][1]+a[j]);
}
for(int j=2;j<=n;j++)
{
for(int k=n;k>=1;k--)
if(num[i][j]+a[k]<que.top())
{
que.pop();
que.push(num[i][j]+a[k]);
}
else
{
break;
}
}
}
for(int i=1;i<=n;i++)
{
a[i]=que.top();
que.pop();
}
for(int i=n;i>=2;i--)
{
printf("%d ",a[i]);
}
printf("%d\n",a[1]);
}
}