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; }
相关文章推荐
- hdu 5701 中位数计数
- HDU 5701 中位数计数
- hdu-5701 中位数计数(中位数)
- HDU 5701 中位数计数(思维,区间)好题
- hdu 5701 中位数计数
- HDU-5701-中位数计数
- HDU 5701 中位数计数 百度之星初赛
- HDU 5701 中位数计数
- HDU 5701 中位数计数 百度之星初赛
- HDU 5701 中位数计数 (暴力 思维题)
- HDU 5701 中位数计数 暴力
- HDU 5701:中位数计数
- HDU 5701 中位数计数 &&HDU 4908 Sequence &&百度之星 1006
- HDU 5701 中位数计数
- HDU 5701-中位数计数
- hdu 5701 中位数计数(重构数组)
- HDU 5701 中位数计数
- HDU 5701 中位数计数 (百度之星初赛)
- hdu_5701_中位数计数
- HDU-5701-中位数计数