1.题面
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18702
2.题意
给你k个数组,每个数组有k个元素.
现在从k个数组中每个都选取1个数字出来,共有k^k种选法
求这k^k个选法中,最小的k个是多少.
3.思路
采用的是刘汝佳大白中的方法.
基本没什么我自己的想法,所以也没什么好说的,不过值得一提的是,这段代码应该是有机会修改成选取最小的任意个个数字的.
4.代码
/*****************************************************************
> File Name: Cpp_Acm.cpp
> Author: Uncle_Sugar
> Mail: uncle_sugar@qq.com
> Created Time: 2016年05月12日 星期四 13时37分31秒
*****************************************************************/
# include <cstdio>
# include <cstring>
# include <cctype>
# include <cmath>
# include <cstdlib>
# include <climits>
# include <iostream>
# include <iomanip>
# include <set>
# include <map>
# include <vector>
# include <stack>
# include <queue>
# include <algorithm>
using namespace std;
const int debug = 1;
const int size = 1000 + 10;
const int INF = INT_MAX>>1;
typedef long long ll;
int a[size];
int b[size];
struct Item{
int s,b;
Item(){}
Item(int s,int b):s(s),b(b){}
bool operator < (const Item& cmper)const{
return s > cmper.s;
}
};
priority_queue<Item> pri_que;
void Merge(int *A,int *B,int *C,int n){
while (!pri_que.empty()) pri_que.pop();
for (int i=0;i<n;i++){
pri_que.push(Item(A[i]+B[0],0));
}
for (int i=0;i<n;i++){
Item T = pri_que.top();pri_que.pop();
C[i] = T.s;
if (T.b+1<n) pri_que.push(Item(T.s - B[T.b] + B[T.b+1],T.b+1));
}
}
int main()
{
std::ios::sync_with_stdio(false);cin.tie(0);
int i,j;
int n;
while (cin >> n){
for (i=0;i<n;i++) cin >> a[i];
sort(a,a+n);
for (i=1;i<n;i++){
for (j=0;j<n;j++)
cin >> b[j];
sort(b,b+n);
Merge(a,b,a,n);
}
for (i=0;i<n;i++){
cout << a[i] << (i==n-1?'\n':' ');
}
}
return 0;
}