建立信息节点Node,存放两个数组中取用的下标和累加值。 建立大根堆,维护Node,按照累加值大到小存放。 使用HashSet维护Node的访问标记。
每次从堆中弹出Node时,取出两个数组中的下标位置,分别看看各自向前移动一个的累加和大小,形成新的节点,再入大根堆,直到满足弹出k个。
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Set;
public class Main {
static class Node{
int a,b,sum;
Node(int a,int b,int sum){
this.a = a;
this.b = b;
this.sum = sum;
}
}
static int x(int a,int b,int cols){
return a*cols + b;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int K = scanner.nextInt();
int [] arr1 = new int[N], arr2 = new int[N];
for(int i=0;i<N;i++) {
arr1[i] = scanner.nextInt();
}
for(int i=0;i<N;i++){
arr2[i] = scanner.nextInt();
}
PriorityQueue<Node> que = new PriorityQueue<Node>((o1,o2)->{ return o2.sum - o1.sum;});
Set<Integer> isVisited = new HashSet<>();
int cnt = 0;
int [] ans = new int[Math.min(K,N*N)];
int a = N-1,b = N - 1;
que.add(new Node(a,b,arr1[a] + arr2[b]));
isVisited.add(x(a,b,N));
while(cnt < K){
Node node = que.poll();
ans[cnt++] = node.sum;
a = node.a;
b = node.b;
isVisited.remove(x(a,b,N));
if( a-1 >= 0 && !isVisited.contains(x(a-1,b,N)) ){
isVisited.add(x(a-1,b,N));
que.add(new Node(a-1,b,arr1[a-1] + arr2[b]));
}
if( b-1 >= 0 && !isVisited.contains(x(a,b-1,N)) ){
isVisited.add(x(a,b-1,N));
que.add(new Node(a,b-1,arr1[a] + arr2[b-1]));
}
}
for(int i=0;i<cnt;i++){
if(i!=0){
System.out.print(" ");
}
System.out.print(ans[i]);
}
}
}