您的位置:首页 > 其它

[Swust OJ 1094]--中位数(巧用set,堆排序)

2015-06-09 01:27 267 查看
题目链接:http://acm.swust.edu.cn/problem/1094/

Time limit(ms): 1000      Memory limit(kb): 32768

中位数(又称中值,英语:Median),统计学中的专有名词,代表一个样本、种群或概率分布中的一个数值,其可将数值集合划分为相等的上下两部分。对于有限的数集,可以通过把所有观察值高低排序后找出正中间的一个作为中位数。如果观察值有偶数个,则中位数不唯一,通常取最中间的两个数值的平均数作为中位数。

Description

多组输入

第一行:一个正整数N (0<N<1000000)
第二行:N个正整数。(0=<A[i]<2^30)

Input

每组数据先输出”Case X:”,X表示测试数据的编号,从1开始。

第二行输出N个数,第i个数对应数组前i个值的中位数。(精确到小数点后一位)

Output

1
2
3
4
5

5
1 2 3 4 5
6
2 5 4 8 7 4

Sample Input

1
2
3
4
5

Case 1:
1.0 1.5 2.0 2.5 3.0
Case 2:
2.0 3.5 4.0 4.5 5.0 4.5

Sample Output

输出换行请使用\r\n
Hint

swust第10届校赛

解题思路:由于数据量太大,那么解题关键就在排序上面了,那么可以巧用堆排序,或者是使用容器 multiset(允许存在相同元素),那么就不会超时了。

multiset 容器用法:http://www.cnblogs.com/zyxStar/p/4542835.html
下面是巧用容器的代码

#include <stdio.h>
#include <string.h>
int lstack[500001], ltot, rstack[500001], rtot, mid;
int Max(int a, int b){
return a > b ? a : b;
}
int Min(int a, int b){
return a<b ? a : b;
}
void lup(int step){
while (step != 1){
if (lstack[step]>lstack[step / 2])lstack[step] ^= lstack[step / 2] ^= lstack[step] ^= lstack[step / 2];
else break;
step = step / 2;
}
if (step == 1 && lstack[1] > mid) lstack[1] ^= mid ^= lstack[1] ^= mid;
}
void ldown(){
if (ltot > 1 && mid < lstack[1]) mid ^= lstack[1] ^= mid ^= lstack[1];
else return;
int step = 1;
while (step * 2 < ltot){
if (step * 2 + 1 >= ltot){
if (lstack[step] < lstack[step * 2])
lstack[step] ^= lstack[step * 2] ^= lstack[step] ^= lstack[step * 2], step = step * 2;
else return;
}
else{
if (lstack[step] <= lstack[step * 2] && lstack[step * 2 + 1] <= lstack[step * 2])
lstack[step] ^= lstack[step * 2] ^= lstack[step] ^= lstack[step * 2], step = step * 2;
else if (lstack[step] <= lstack[step * 2 + 1] && lstack[step * 2] <= lstack[step * 2 + 1])
lstack[step] ^= lstack[step * 2 + 1] ^= lstack[step] ^= lstack[step * 2 + 1], step = step * 2 + 1;
else return;
}
}
}
void rup(int step){
while (step != 1){
if (rstack[step]<rstack[step / 2])rstack[step] ^= rstack[step / 2] ^= rstack[step] ^= rstack[step / 2];
else break;
step = step / 2;
}
if (step == 1 && rstack[1]<mid) rstack[1] ^= mid ^= rstack[1] ^= mid;
}
void rdown(){
if (rtot>1 && mid>rstack[1]) mid ^= rstack[1] ^= mid ^= rstack[1];
else return;
int step = 1;
while (step * 2 < rtot){
if (step * 2 + 1 >= rtot){
if (rstack[step] > rstack[step * 2])
rstack[step] ^= rstack[step * 2] ^= rstack[step] ^= rstack[step * 2], step = step * 2;
else return;
}
else{
if (rstack[step] >= rstack[step * 2] && rstack[step * 2 + 1] >= rstack[step * 2])
rstack[step] ^= rstack[step * 2] ^= rstack[step] ^= rstack[step * 2], step = step * 2;
else if (rstack[step] >= rstack[step * 2 + 1] && rstack[step * 2] >= rstack[step * 2 + 1])
rstack[step] ^= rstack[step * 2 + 1] ^= rstack[step] ^= rstack[step * 2 + 1], step = step * 2 + 1;
else return;
}
}
}
int main()
{
int t = 1, n, i;
while (scanf("%d", &n) != EOF){
printf("Case %d:\r\n", t++);
scanf("%d", &mid);
ltot = rtot = 1;
printf("%.1lf", (double)mid);
for (i = 1; i < n; i++){
if (i % 2){
scanf("%d", &lstack[ltot]);
lup(ltot);
rdown();
ltot++;
printf(" %.1lf", (mid + lstack[1]) / 2.0);
}
else{
scanf("%d", &rstack[rtot]);
rup(rtot);
ldown();
rtot++;
printf(" %.1lf", (double)mid);
}
}
printf("\r\n");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: