您的位置:首页 > 其它

HDU 5701 中位数计数

2017-09-12 09:43 295 查看


中位数计数

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1902    Accepted Submission(s): 675


Problem Description

中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数。

现在有n个数,每个数都是独一无二的,求出每个数在多少个包含其的区间中是中位数。

 

Input

多组测试数据

第一行一个数n(n≤8000)

第二行n个数,0≤
 每个数≤109,

 

Output

N个数,依次表示第i个数在多少包含其的区间中是中位数。

 

Sample Input

5
1 2 3 4 5

 

Sample Output

1 2 3 2 1

 
其实这个题我现在也不明白,可能是智商不够吧.....;(感觉这个题有bug,,,如果输入1,1,1,应该输出什么呢???AC的代码输出是1,1,1;但应该是这样吗???还有到底应不应该排序之后再找中位数???如果排序是应该所有数字都排序还是、找哪个区间哪个区间排序???)

对每个数前后都扫一遍,是O(n^2)的复杂度(8000不算大);对第i个数后边的数,每遇到一个比他大的就加1,小的就减(用cnt记录, cnt就代表数组下标,has[mid+cnt]表示前边数大或小的个数);然后对前边的数没遇到比他大的就减1,大的就加1(如果前后cnt互为相反数,答案就加1;);
为什么互为相反数就可以呢?先看看什么是相反数:两个数符号相反,绝对值相同即为相反数,也就是说相加等于0;那么好了,前后cnt相加等于零,这也就意味着i的前后大于他的数等于小于他的数,i此时就是一个中位数;
代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#define MAX 8000+5

using namespace std;

const int mid = 8000;
int num[MAX];               //记录输入的数;
int has[MAX<<1];
int main()
{
int n;
while(cin >> n){
for(int i=1; i<=n; i++)
cin >> num[i];
for(int i=1; i<=n; i++){
int ans=0;
int cnt=0;
memset(has, 0, sizeof(has));
has[mid]=1;                   //本身是个区间,自己就是个中位数;
for(int j=i+1; j<=n; j++){
cnt+=num[j]>num[i]?1:-1;
has[mid+cnt]++;
}
cnt=0;
ans+=has[mid];
for(int j=i-1; j>=1; j--){
cnt+=num[j]>num[i]?-1:1;
ans+=has[mid+cnt];
}
printf("%d%c", ans, i==n?'\n':' ');
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: