天天看點

CDOJ_1063 秋實大哥與妹紙(堆結構) 秋實大哥與妹紙

秋實大哥與妹紙

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 1500/1500KB (Java/Others)

緻中和,天地位焉,萬物育焉。秋實大哥是一個追求中庸的人。 雖然秋實大哥的仰慕者衆多,但秋實大哥不喜歡極端的妹紙。是以他想從所有仰慕自己的妹紙中挑選出一個符合中庸之道的。 每一個妹紙對秋實大哥的仰慕程度可以用一個整數ai來表示,秋實大哥想要找出這些數的中位數。

計算有限個數的資料的中位數的方法是

把所有的同類資料按照大小的順序排列。如果資料的個數是奇數,則中間那個資料就是這群資料的中位數;
   
   
    如果資料的個數是偶數,則中間那
    2
    個資料的算術平均值就是這群資料的中位數。
         

Input

第一行有一個整數n,表示秋實大哥的仰慕者數目。 接下來n行,每行有一個正整數ai。 1≤n≤250000,1≤ai<231。

Output

輸出這n個數的中位數,保留一位小數。

Sample input and output

Sample Input Sample Output
3
1
2
3      
2.0      

Hint

注意記憶體大小限制。

Source

2015 UESTC Training for Data Structures

記憶體卡的很死,是以先讀入前一半的資料,維護一個大根堆,然後把後一半的資料依次讀入,如果比大根堆的根小的話,就與其做交換,再維護這個大根堆。 最後根據n的奇偶性輸出中位數就好了。

AC代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define maxn 125005
unsigned int num[maxn];
void heap_output(unsigned int *num, int n)
{
	int i;
	for (i = 0; i < n; i++)
		printf("%u ", num[i]);
	printf("\n");
}
void heap_make(unsigned int *num, int s, int n)
{
	int j; unsigned int t;
	while (2 * s + 1 < n)
	{
		j = 2 * s + 1;
		if (j + 1 < n)
		{
			if (num[j] < num[j + 1])
				j++;
		}
		if (num[s] < num[j])
		{
			t = num[s];
			num[s] = num[j];
			num[j] = t;
			s = j;
		}
		else break;
	}
}
int main()
{
	unsigned int temp;
	int n, mid;
	double ans;
	scanf("%d", &n);
	memset(num, 0, sizeof(unsigned int)*maxn);
	mid = n / 2 + 1;
	int i;
	for (i = 0; i < mid; i++)
		scanf("%u", &num[i]);
	for (i = mid / 2 - 1; i >= 0; i--)
		heap_make(num, i, mid);
	
	for (i = mid; i < n; i++)
	{
		scanf("%u", &temp);
		if (temp < num[0])
		{
			num[0] = temp;
			heap_make(num, 0, mid);
		}
	}
	
	if (n % 2)
	{
		ans = num[0];
	}
	else
	{
		double t1, t2;
		t1 = num[0];
		t2 = (num[1] > num[2]) ? num[1] : num[2];
		ans = (t1 + t2) / 2.0;
	}
	printf("%.1f", ans);
	
	return 0;
}
           

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 1500/1500KB (Java/Others)

繼續閱讀