做这个题首先思考两个问题
由这两个得出,要求n个数组每一个数组m个值。数组1和数组2的和找出最小的m个,再用来和数组3求和,找到最小的m个,终于得到全部的数组中的最小的m个
因为每一个数组都是有序的,并且我们要求的最小的m个。数组a[i][j]+队列中的值 > 队首的值,那么a[i][j]加上队列中以后的值都会大于队首。对于我们要求解的最小的m个值无意义。队列中保存了当前数组到之前全部数组的最小的m个和,不断更新队列
#include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; int a[110][2100] , b[2100] ; priority_queue <int> p ; int main() { int i , j , k , n , m , t ; scanf("%d", &t); while(t--) { scanf("%d %d", &n, &m); for(i = 0 ; i < n ; i++) { for(j = 0 ; j < m ; j++) scanf("%d", &a[i][j]); sort(a[i],a[i]+m); } for(i = 0 ; i < m ; i++) p.push(a[0][i]) ; for(i = 1 ; i < n ; i++) { for(j = 0 ; j < m ; j++) { b[j] = p.top(); p.pop(); } for(j = 0 ; j < m ; j++) { for(k = m-1 ; k >= 0 ; k--) { if(j == 0) p.push( a[i][j]+b[k] ); else { if( a[i][j] + b[k] < p.top() ) { p.pop(); p.push(a[i][j]+b[k]); } else break; } } } } for(j = 0 ; j < m ; j++) { b[j] = p.top(); p.pop(); } for(j = m-1 ; j >= 0 ; j--) { if(j == 0) printf("%d ", b[j]); else printf("%d ", b[j]); } } return 0; }
版权声明:转载请注明出处:http://blog.csdn.net/winddreams