UVA

来源:互联网 发布:程序员经常熬夜吗 编辑:程序博客网 时间:2024/05/21 19:49

思路:
  相信大家都会思考这个问题:为什么每次要选择最小的那个元素的下一个元素呢?当把最小元素出队之后,还剩余n-1个元素,如果不取那个最小元素的下一个元素,就会取其他n-1个元素的下一个元素,那么加入的这个元素一定是大于它的前一个元素的,一定不会是最小的元素。要保证每次都取得的都是最小n个元素是不可能的,只能保证当前未取的元素一定在队列中就好。那么我们一定要加入出队的最小元素的下一个元素


AC代码

//#define LOCAL#include <stdio.h>#include <algorithm>#include <queue>using namespace std;struct node{    int s, index;    node(int s, int index):s(s), index(index) {}    bool operator < (const node& a) const {        return s > a.s;    }};void mergeTwoArr(int* a, int* b, int* c, int n) {    priority_queue<node> que;    for(int i = 0; i < n; i++) {        que.push(node(a[i]+b[0], 0));    }    for(int i = 0; i < n; i++) {        node small = que.top(); que.pop();        c[i] = small.s;        int index = small.index;        if(index+1 < n) {            small.s = small.s + b[index+1] - b[index];            small.index += 1;            que.push(small); //将当前可选最小值加入队列        }    }}const int maxn = 750+5;int sum[maxn], now[maxn];int main() {#ifdef LOCAL    freopen("data.in", "r", stdin);    freopen("data.out", "w", stdout);#endif // LOCAL    int n;    while(scanf("%d", &n) == 1) {        //初始化sum数组        for(int i = 0; i < n; i++) {            scanf("%d", &sum[i]);        }        sort(sum, sum+n);        for(int i = 1; i < n; i++) {            for(int j = 0; j < n; ++j) {                scanf("%d", &now[j]);            }            sort(now, now+n);            mergeTwoArr(sum, now, sum, n);        }        for(int i = 0; i < n; i++) {            printf("%d%c", sum[i], i == n-1 ? '\n' : ' ');        }    }    return 0;}

如有不当之处欢迎指出!

原创粉丝点击