秋实大哥与妹纸
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)
致中和,天地位焉,万物育焉。秋实大哥是一个追求中庸的人。
虽然秋实大哥的仰慕者众多,但秋实大哥不喜欢极端的妹纸。所以他想从所有仰慕自己的妹纸中挑选出一个符合中庸之道的。
每一个妹纸对秋实大哥的仰慕程度可以用一个整数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;
}