链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far.
输入描述:
The first line of input contains a single integer P(1≤P≤1000)P(1 \leq P \leq 1000)P(1≤P≤1000), which is the number of data sets that follow. The first line of each data set contains the data set number, followed by a space, followed by an odd decimal integer M(1≤M≤9999)M (1 \leq M \leq 9999)M(1≤M≤9999), giving the total number of signed integers to be processed. The remaining line(s) in the dataset consists of the values, 10 per line, separated by a single space. The last line in the dataset may contain less than 10 values.输出描述:
For each data set the first line of output contains the data set number, a single space and the number of medians output (which should be one-half the number of input values plus one). The output medians will be on the following lines, 10 per line separated by a single space. The last line may have less than 10 elements, but at least 1 element. There should be no blank lines in the output.示例1
输入
复制3 1 9 1 2 3 4 5 6 7 8 9 2 9 9 8 7 6 5 4 3 2 1 3 23 23 41 13 22 -3 24 -31 -11 -8 -7 3 5 103 211 -311 -45 -67 -73 -81 -99 -33 24 56
3 1 9 1 2 3 4 5 6 7 8 9 2 9 9 8 7 6 5 4 3 2 1 3 23 23 41 13 22 -3 24 -31 -11 -8 -7 3 5 103 211 -311 -45 -67 -73 -81 -99 -33 24 56输出
复制1 5 1 2 3 4 5 2 5 9 8 7 6 5 3 12 23 23 22 22 13 3 5 5 3 -3 -7 -3
1 5 1 2 3 4 5 2 5 9 8 7 6 5 3 12 23 23 22 22 13 3 5 5 3 -3 -7 -3
翻译
题目描述: 对于这个问题,你需要编写一个程序,读取一系列32位有符号整数。在每次读取到奇数索引值时,输出目前接收到的元素的中位数(中间值)。
输入描述: 输入的第一行包含一个整数 P(1≤P≤1000),表示数据集的数量。每个数据集的第一行包含数据集编号,后跟一个空格,然后是一个奇数十进制整数 M(1≤M≤9999),表示要处理的有符号整数的总数。数据集的其余行由值组成,每行有10个值,用单个空格分隔。数据集的最后一行可能包含少于10个值。
输出描述: 对于每个数据集,输出的第一行包含数据集编号,后跟一个空格和输出的中位数数量(应为输入值数量的一半加一)。下面是输出的中位数,每行10个值,用单个空格分隔。最后一行可能少于10个元素,但至少有1个元素。输出中不应有空行。
解题思路
创建一个最大堆
maxHeap
和一个最小堆minHeap(我这里为方便名字用的p,q),大根堆维护序列较小的一半,小根堆维护较大的一半。
- 将第一个整数作为基准值(记为
mid
)放入最大堆。- 遍历剩余的整数:
- 如果当前整数小于等于基准值
mid
,将其插入最小堆minHeap
中。- 如果当前整数大于基准值
mid
,将其插入最大堆maxHeap
中。- 检查堆的大小,保证最大堆的大小等于或比最小堆的大小多一。如果不满足,则调整堆的大小,即将最大堆的根节点弹出并插入到最小堆中,或将最小堆的根节点弹出并插入到最大堆中。
- 输出当前接收到的元素的中位数。中位数可以通过最大堆和最小堆的根节点来获得。
详细代码:
#include<iostream>
#include<math.h>
#include<vector>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
typedef int ll;
using namespace std;
priority_queue<int, vector<int>, greater<int> >q;//最小堆
priority_queue<int, vector<int>>p;//最大堆
int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int P;
P = read();
while (P--)
{
while (!q.empty())q.pop();
while (!p.empty())p.pop();
int index, num, m;
index = read();num = read();
printf("%d %d\n", index, (num + 1) / 2);
p.push(read());//奇数索引放入最小堆
printf("%d ", p.top());//输出第一个值
for (int i = 2;i <= num;i++)
{
int a = read();
if (a <= p.top())p.push(a);
else q.push(a);
int g = q.size(), l = p.size();
if (g > l + 1) { p.push(q.top());q.pop(); }
//确保最大堆的大小大于等于最小堆加1,不满足则调节
else if (l > g) { q.push(p.top()); p.pop(); }//记得把移动的数删掉
if (i & 1) {
g = q.size(), l = p.size();
// printf("g=%d l=%d ",g,l);
if (g >= l)printf("%d ", q.top());
else printf("%d ", p.top());
if (i % 20 == 19 && i != num)printf("\n");//换行
}
}
printf("\n");//有点重要的换行
}
return 0;
}