中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数。
现在有n个数,每个数都是独一无二的,求出每个数在多少个包含其的区间中是中位数。
Input第一行一个数n(n<=8000)
第二行n个数,0<=每个数<=10^9OutputN个数,依次表示第i个数在多少包含其的区间中是中位数。
Sample Input
5 1 2 3 4 5Sample Output
1 2 3 2 1
解:显然一个数要是中位数,比他大的数的个数要和比他小的数的个数相等
因为必须包括这个数,所以我们从这个数出发,分别往左往右寻找,如果比他小res--,比他大res++
比如 你先往左边 ,显然res==0时 ,ans++ ,其他的话记录 num[8000+res]++ ;
之所以+8000是因为res可能为负且最大为8000
然后往右 res归零 ,如果比他小res--,比他大res++
不过 ans+=num[8000-res] 因为,假设你res为 1 ,那么所以左边的res为-1的情况,这个区间的值都可以使他为中位数
#include<stdio.h>
#include<string.h>
using namespace std;
int a[81111];
int num[200000];
int main()
{
int n,ans;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
ans=1;//只有自己的情况
memset(num,0,sizeof(num));
num[8000]=1;//只有自己的情况也要记录
int res=0;
for(int j=i-1;j>=1;j--) //往左
{
if(a[j]>a[i])
res++;
else
res--;
num[8000+res]++;//记录状态
if(res==0)//如果是0 是可以的
ans++;
}
res=0;
for(int j=i+1;j<=n;j++)
{
if(a[j]>a[i])
res++;
else
res--;
ans+=num[8000-res];//加上左边和res成相反关系的个数
}
if(i!=1) printf(" ");
printf("%d",ans);
}
printf("\n");
}
10
10 7 4 8 2 3 1 9 6 5
1 4 6 1 2 6 1 1 4 4