每日一题7.23

P1168 中位数 - 洛谷

题目描述

给定一个长度为 N 的非负整数序列 A,对于前奇数项求中位数。

输入格式

第一行一个正整数 N。

第二行 N 个正整数 A1…N​。

输出格式

共 ⌊2N+1​⌋ 行,第 i 行为 A1…2i−1​ 的中位数。

输入输出样例

输入 #1复制

7
1 3 5 7 9 11 6

输出 #1复制

1
3
5
6

输入 #2复制

7
3 1 5 9 8 7 6

输出 #2复制

3
3
5
6

说明/提示

对于 20% 的数据,N≤100;

对于 40% 的数据,N≤3000;

对于 100% 的数据,1≤N≤100000,0≤Ai​≤109。

对于这个题,我感觉很像插入排序,所以我就边插入边输出了一次,但是这样的话时间会是n方的就超时了,然后看题解说用堆排比较好:

以下是代码:

#include
using namespace std;
#define int long long
//void solve()这里使用插入排序,时间复杂度O(n^2),所以超时了
//{
//	int n;
//	cin >> n;
//	vector a(n);
//	for (int i = 0; i < n; i++)
//		cin >> a[i];
//	for (int i = 0; i < n; i += 2)
//	{
//		if(i==0)
//			cout<=0; k--)
//				{
//					a[k + 1] = a[k];
//					if (temp>=a[k])
//					{
//						a[k+1]=temp;
//						break;
//					}
//				}
//			}
//			cout << a[i / 2]<> n;
	vector a(n);
	for (int i = 0; i < n; i++)
		cin >> a[i];
	priority_queue, greater> pql;//小顶堆,大根堆
	priority_queue, less> pqs;//大顶堆,小根堆
	int mid=0;
	for (int i = 0; i < n; i++)
	{
		if (i == 0)
		{
			mid = a[i];
			cout << mid << endl;
		}
		else
		{
			if (a[i] > mid)
				pql.push(a[i]);
			else
				pqs.push(a[i]);
			if (i % 2==0)
			{
				if (pql.size() > pqs.size())//大根堆的元素个数大于小根堆的元素个数,则取出大根堆的最小值
				{
					int temp = pql.top();
					pql.pop();
					pqs.push(mid);
					mid = temp;
				}
				else if(pql.size()> t;
	while (t--)
	{
		solve();
	}
	return 0;
}

然后还有黑科技的,就是直接用vector的insert

#include
using namespace std;
#define int long long
void solve()
{
	int n;
	cin >> n;
	vector a;
	for (int i = 0; i < n; i++)
	{
		int x;
		cin >> x;
		a.insert(lower_bound(a.begin(), a.end(), x), x);
		if (i % 2 == 0)
			cout << a[i / 2] << endl;
	}
	
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t = 1;
	//cin >> t;
	while (t--)
	{
		solve();
	}
	return 0;
}

你可能感兴趣的:(每日一题,算法)