51nod 1682 中位数计数

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

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


Input
第一行一个数n(n<=8000)
第二行n个数,0<=每个数<=10^9
Output
N个数,依次表示第i个数在多少包含其的区间中是中位数。
Input示例
5
1 2 3 4 5
Output示例

1 2 3 2 1




对于第i个,我们有四种可能

1: 单独这一个

2: j 到 i

3: i 到 j

4: j1 到 i 到 j2

我们需要挨个求。我们现在求第i个

cnt=1 //第一个肯定满足

我们这里一个tongji,记录1到i-1中比当前值大小的情况,对于每一个位置j,如果当前值大于i,则+1,否则-1.

如果到第j位,tongji==0,说明比i大的和比i小的一样多,那么当前j到i,i肯定就是中位数。 这样求出说有j到i的情况

同时我们统计一下i前面所有的可能性。也就是j到i距离为1的有几个,距离为2的有几个。 方便后面查询 j1 到 i 到 j2。


之后我们在遍历i+1到n ,相同的办法先找出所有的i到j的情况。

同时对于第j个,假设当前第j个的tongji值为1,这是在i到j找到的, 如果 前面1到i-1之间也有tongji为1的,那么一连接,不就是第四种情况嘛。 可能有人疑问,后面1和前面1,连接后不是0啊.不能保证i是中位数。我们这段遍历时,我们反着来即可,1-i我们是小的+1,大的-1.我们这里小的-1,大的+1.这样来遍历不就可以了嘛。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<iostream>
using namespace std;
int a[10000];
int tongji[10000];
int shuchu[10000];
int xiangtong[20000];
int n,cnt,dangqian;
int main()
{
    cin>>n;


    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=n;i++) //对于第i个
    {
        cnt=1;//自身就是一个
        dangqian=a[i];//当前值
        memset(tongji,0,sizeof(tongji));
        memset(xiangtong,0,sizeof(xiangtong));
        for(int j=i-1;j>=1;j--)
        {
            if(a[j]<dangqian)//如果第j个小于当前值
            {
                tongji[j]=tongji[j+1]+1; //+!
            }
            else
            {
                tongji[j]=tongji[j+1]-1; //-1
            }
            xiangtong[tongji[j]+n]++; //统计相同情况的总个数
            if(tongji[j]==0)//如果当前为0,说明没大也没小,或者大的等于小的,抵消了。那么j到i就是中位数
            {
                cnt++;
            }
        }
        for(int j=i+1;j<=n;j++)
        {
            if(a[j]<=dangqian)
            {
                tongji[j]=tongji[j-1]-1;
            }
            else
            {
                tongji[j]=tongji[j-1]+1;
            }
            if(tongji[j]==0)
            {
                cnt++;
            }
            if(xiangtong[tongji[j]+n]>0)
            {
                cnt+=xiangtong[tongji[j]+n];
            }


        }






        shuchu[i]=cnt;


    }
    for(int i=1;i<n;i++)
        cout<<shuchu[i]<<" ";
    cout<<shuchu[n]<<endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值