POJ3784 Running Median 对顶堆维护动态中位数(思维)

1.题目描述:

Running Median
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 1818 Accepted: 885

Description

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.

Input

The first line of input contains a single integer 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), 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.

Output

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.

Sample Input

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

Sample Output

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

Source


2.题意概述:

1000个case
每个case  
输入若干个数,对第k个输入,如果k为奇数,则输出前k个数的中位数

3.解题思路:

借鉴了网上的对顶堆数据结构,实际上就开两个堆,一个大顶堆存小数,一个小顶堆存大数,保证大顶堆中任意元素小于小顶堆,这样小顶堆底部就是中位数,有张图:

4.AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <functional>
#include <cmath>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <ctime>
#define INF 0x7fffffff
#define maxn 100100
#define N 1111
#define eps 1e-6
#define pi acos(-1.0)
#define e 2.718281828459
#define mod (int)1e9 + 7
using namespace std;
typedef long long ll;
priority_queue<int, vector<int>, less<int>> big;
priority_queue<int, vector<int>, greater<int>> small;
vector<int> v;
void add(int x)
{
	if (small.empty())
	{
		small.push(x);
		return;
	}
	if (x > small.top())
		small.push(x);
	else
		big.push(x);
	while (small.size() < big.size())
	{
		small.push(big.top());
		big.pop();
	}
	while (small.size() > big.size() + 1)
	{
		big.push(small.top());
		small.pop();
	}
}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	long _begin_time = clock();
#endif
	int t;
	scanf("%d", &t);
	while (t--)
	{
		while (!small.empty())
			small.pop();
		while (!big.empty())
			big.pop();
		v.clear();
		int kase, n;
		scanf("%d%d", &kase, &n);
		for (int i = 0; i < n; i++)
		{
			int x;
			scanf("%d", &x);
			add(x);
			if (i % 2 == 0)
				v.push_back(small.top());
		}
		printf("%d %d\n", kase, (n + 1) / 2);
		for (int i = 0; i < (int)v.size(); i++)
		{
			if (i > 0 && i % 10 == 0)
				puts("");
			if (i % 10)
				putchar(' ');
			printf("%d", v[i]);
		}
		puts("");
	}

#ifndef ONLINE_JUDGE
	long _end_time = clock();
	printf("time = %ld ms.", _end_time - _begin_time);
#endif
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值