UVa 11997 (优先队列 多路归并) K Smallest Sums
2015-03-16 15:10
337 查看
考虑一个简单的问题,两个长度为n的有序数组A和B,从每个数组中各选出一个数相加,共n2中情况,求最小的n个数。
将这n2个数拆成n个有序表:
A1+B1≤A1+B2≤...
A2+B1≤A2+B2≤...
...
An+B1≤An+B2≤...
然后用优先队列合并成一个有序表即可。队列中需要记录两个数的和s,以及在B中的下标b,
比如Aa+Bb出队以后,应该将Aa+B(b+1) = Aa + Bb - Bb + Bb+1 = s - Bb + bb+1入队
对于书上最后的一个思考问题,merge函数中对A[0]又读又写,会不会出错。答案当然是不会的,因为进入到函数内部你会发现,对A数组其实是先读后写的。
代码君
将这n2个数拆成n个有序表:
A1+B1≤A1+B2≤...
A2+B1≤A2+B2≤...
...
An+B1≤An+B2≤...
然后用优先队列合并成一个有序表即可。队列中需要记录两个数的和s,以及在B中的下标b,
比如Aa+Bb出队以后,应该将Aa+B(b+1) = Aa + Bb - Bb + Bb+1 = s - Bb + bb+1入队
对于书上最后的一个思考问题,merge函数中对A[0]又读又写,会不会出错。答案当然是不会的,因为进入到函数内部你会发现,对A数组其实是先读后写的。
#include <cstdio> #include <queue> #include <algorithm> using namespace std; const int maxn = 750 + 10; int a[2][maxn]; void scan(int& x) { char c; while(c = getchar(), c < '0' || c > '9'); x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x*10 + c - '0'; } struct Node { int sum, b; Node(int s, int b):sum(s), b(b) {} bool operator < (const Node& rhs) const { return sum > rhs.sum; } }; void merge(int n, int* A, int* B, int* C) { priority_queue<Node> Q; for(int i = 0; i < n; i++) Q.push(Node(A[i]+B[0], 0)); for(int i = 0; i < n; i++) { Node t = Q.top(); Q.pop(); int b = t.b, sum = t.sum; C[i] = sum; if(b + 1 < n) Q.push(Node(sum-B[b]+B[b+1], b+1)); } } int main() { //freopen("in.txt", "r", stdin); int k; while(scanf("%d", &k) == 1) { for(int i = 0; i < k; i++) scan(a[0][i]); sort(a[0], a[0] + k); for(int i = 1; i < k; i++) { for(int j = 0; j < k; j++) scan(a[1][j]); sort(a[1], a[1] + k); merge(k, a[0], a[1], a[0]); } for(int i = 0; i < k; i++) { if(i) printf(" "); printf("%d", a[0][i]); } puts(""); } return 0; }
代码君
相关文章推荐
- K Smallest Sums(Uva 11997) 多路归并+优先队列
- uva11997 K Smallest Sums&&UVALive 3135 Argus(优先队列,多路归并)
- uva 11997 K smallest sums (优先队列 多路归并)
- UVa - 11997 K Smallest Sums(优先队列多路归并)
- UVa 11997 K Smallest Sums (优先队列 & k路归并化为两两归并)
- 【优先队列之多路合并】UVA - 11997 K Smallest Sums
- UVA 11997--K Smallest Sums+优先队列用于多路归并
- (UVa 11997)K Smallest Sums --多路归并问题,优先队列
- UVA 11997 K Smallest Sums——多路归并
- UVA 11997 K Smallest Sums(多路归并求前k个最小和的值)
- UVA 11997 - K Smallest Sums(多路归并)
- UVA 11997 K Smallest Sums (多路归并)
- 优先队列 UVA 11997 K Smallest Sums
- 多路归并优先队列——UVA 11997
- UVA11997 - K Smallest Sums 优先队列,多路归并
- 思路题,多路归并(K Smallest Sums,UVA 11997)
- UVA11997:K Smallest Sums(多路归并求最小k个和)
- uva 11997 k个最小和(优先队列实现多路归并)题解
- UVA 11997 K Smallest Sums (多路归并)
- UVa - 11997 - K Smallest Sums贪心多路归并