AcWing 106. 动态中位数——Java代码版
原题链接
中等
作者:
三玖天下第一
,
2021-03-05 16:31:11
,
所有人可见
,
阅读 341
import java.io.*;
import java.util.*;
public class 动态中位数 {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));
int t = Integer.parseInt(reader.readLine().trim());
while(t-- > 0){
String[] temp = reader.readLine().split(" ");
int num = Integer.parseInt(temp[1]);
writer.write(temp[0]+" "+(num+1)/2+"\n");
/**
* 创建两个堆,一个大根堆,一个小根堆
* 大根堆用于存放比中位数小的数据,小根堆用于存放大于中位数的数据
* 这里我们规定大根堆的堆顶数据即为当前输入数据的中位数
*/
PriorityQueue<Integer> up = new PriorityQueue<>();
PriorityQueue<Integer> down = new PriorityQueue<>((o1, o2) -> o2-o1);
int cnt = 0;
for (int i = 0; i < num; i++) {
if(i % 10 == 0) temp = reader.readLine().split(" ");
int x = Integer.parseInt(temp[i % 10]);
//当大根堆为空或者输入数据小于大根堆堆顶数据(即中位数)时,将该数据插入大根堆,否则插入小根堆
if (down.isEmpty() || x <= down.peek()){
down.add(x);
}else up.add(x);
//当大根堆中的数据数量比小根堆大2,将数据向小根堆转移一位
if (down.size() > up.size()+1) up.add(down.poll());
if (up.size() > down.size()) down.add(up.poll());
if (i%2 == 0){//当输入的数据为奇数时,输出当前数据的中位数(即大根堆的堆顶数据)
writer.write(down.peek()+" ");
if (++cnt % 10 == 0) writer.write("\n");
}
}
if (cnt%10 != 0) writer.write("\n");
}
writer.flush();
}
}