1 条题解
-
0
题意;m * n 的矩阵 m行n列,每一行取一个数加起来,形成一个排列,升序输出排列和最小的前n个。
解题思路:维护两个数组,和一个优先队列,两个数组滚动使用。先对输入进来的每一行进行排序(升序)。把相邻的两行的值的和压入队列,在这个过程中队列中只保留n个元素,即比较小的n个, 多出n个就, 弹出最大的。
具体步骤如下:
1,读入第一行a[i],把第一行进行排序,再读入第二行b[i],用第一行的最小值a[0]与第二行的每个数相加,压入队列。
2,循环a[1]...a[n]与b[0]...b[n]的和与队列中的最大值进行比较,如果和值小于最大值就弹出最大值,压入和值,如果大于等于就break(因为是b[i]排过序的,这里和值如果大于等于,后面的和值也只能是大于等于)
3,按升序更新a[i],a[i]就是队列中的值, 反复第2步,直到结束. 代码:
#include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<list> #include<iostream> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define MAX_N 2005 using namespace std; int n, m; int a[MAX_N]; int b[MAX_N]; priority_queue<int> pq; int main() { int t; scanf("%d", &t); while(t--) { scanf("%d%d", &m, &n); for(int i = 0 ; i < n; i++) scanf("%d", &a[i]); sort(a, a + n); while(--m) { for(int i = 0 ; i < n ; i++) { scanf("%d", &b[i]); pq.push(a[0] + b[i]); } sort(b, b + n); for(int i = 1 ; i < n ; i++) { for(int j = 0 ; j < n ; j++) { if(a[i] + b[j] >= pq.top()) break; pq.pop(); pq.push(a[i] + b[j]); } } for(int i = n -1 ; i >= 0 ; i--) { a[i] = pq.top(); pq.pop(); } } for(int i = 0 ; i < n - 1 ; i++) { printf("%d ", a[i]); } printf("%d\n", a[n -1]); } return 0; }
- 1
信息
- ID
- 1443
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 9
- 已通过
- 1
- 上传者