中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数。
现在有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