HDU 5701-中位数计数

来源:互联网 发布:linux apache ab测试 编辑:程序博客网 时间:2024/05/20 09:06

中位数计数

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2065    Accepted Submission(s): 717


题目链接:点击打开链接


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

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

Input
多组测试数据

第一行一个数n(n8000)

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

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


Sample Input
5
1 2 3 4 5
 


Sample Output
1 2 3 2 1

题意:
肯定有人对题意理解的不对,就像第一次看题的我,本题是给你一组数(注意这组数不是排好序的,是无序的,题上的测试数据只是一个特例),然后让你对这组数进行遍历,找出每个数所在的区间里它是中位数的情况,比如测试数据中的4,它对应的值是2,包含4的区间有(1 2 3 4)(2 3 4)(3 4)(4)(4 5)(1 2 3 4 5)(2 3 4 5)(3 4 5) ,但是他在区间(4)和区间(3 4 5)中是中位数,还有一点就是,本题因为没有重复的数字,每个数字都是独一无二的,所以不存在以该数为中位数的偶数个数字的区间(你想啊,因为偶数个数的中位数是两个数的加和除以2,但是没有两个一样的数字,所以中位数肯定不为该数)。


分析:
我们可以定义一个神秘的数组,之所以说它神秘,是它的巧妙之处可以帮我们解决所有的问题,这个数组只要理解了,本题就过了,说说思想吧,就是先扫一下 i 右边的数,求出比它大的数的个数减去比它小的个数的差值,然后再扫一下 i 左边的数,求出比它小的数的个数减去比它大的个数的差值,如果两个差值相等的话,是不是该数就是这个区间里的中位数了,恩恩,就这样,但代码中你必须要理解好 h 数组的含义。、



#include <stdio.h>#include <string.h>const int INF = 8005;int s[INF],h[INF*2];///h数组一定要定义两倍大,以防数组下标越界int main(){    int n,ans,num;    while(scanf("%d",&n)!= EOF)    {        for(int i=0;i<n;i++)            scanf("%d",&s[i]);        for(int i=0;i<n;i++)        {            num=0,ans=0;///从左扫从右扫之前都要将num置0,它存的是比该数大和比该数小的数            memset(h,0,sizeof(h));///初始化将该数组刷为0            h[INF]++;///这个表示自身一个数的情况,也是可行的            for(int j=i+1;j<n;j++)///从右边扫            {                if(s[j]>s[i])///如果大于该数,num++                    num++;                else///否则num--,这样就可以求出差值了                    num--;                h[INF+num]++;///这个带点自己理解,动手模拟            }            num=0;            ans+=h[INF];///让区间里比它大的数和比它小的数相等的时候的情况累加            for(int j=i-1;j>=0;j--)///扫左边            {                if(s[j]<s[i])///如果小于该数,num++                    num++;                else///否则num--                    num--;                ans+=h[INF+num];                /**如果该数组里再扫右边得时候已经统计过,那么再遇见,就代表该区间可以                让该数成为中位数**/            }            if(i<n-1)///这个是控制空格的情况                printf("%d ",ans);            else                printf("%d\n",ans);        }    }    return 0;}