HDU 5701 中位数计数 (思维题)

题目链接

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

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

Input

多组测试数据 

第一行一个数n(n≤8000)n(n≤8000) 

第二行nn个数,0≤0≤每个数≤109≤109,

Output

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

Sample Input

5
1 2 3 4 5

Sample Output

1 2 3 2 1

PS:这个题是一个很不错的思维题,首先我们声明一个ans数组保存答案,一个数组num保存左边右边比当前数打或者小的数的个数,已a[i]来讨论,有三种情况。

1.讨论它左边的区间,从(i-1)向左遍历,注意一定是这样遍历,不然不能够保证连续区间,然后声明一个num记录比它大或者比他小的数,遇到比它大的数,num++,反之num--,如果num==0,说明在他的左区间比他大的数和比它小的数个数一样,它直接能够是中位数,ans[i]++,因为num可以是负数,所以在数组记录的时候需要提前加个大数,直接num[maxn+sum]++。

2.讨论它右边的区间,从(i+1)向右遍历。其他情况和向左遍历的情况一样。

3.同时讨论a[i]的左右区间。直接ans[i]+=num[maxn-sum];说一下为什么这样可以。若是左边有两个比它大的,num记录的num[maxn+2]等于1,需要在右边右边找两个比它小的数num==-1。所以直接ans[i]+=num[maxn-(-2)]等于ans[i]+=num[maxn+2]。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=8e3+10;
const int mod=10007;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
typedef long long ll;
using namespace std;
int main()
{
    int n,a[maxn],ans[maxn];
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            ans[i]=1;
        }
        for(int i=1;i<=n;i++)
        {
            int num[maxn<<2],sum=0;
            me(num,0);
            for(int j=i-1;j>=1;j--)
            {
                if(a[j]>a[i])
                    sum++;
                else
                    sum--;
                if(sum==0)//他的左区间比他大的数和比它小的数个数一样,它直接能够是中位数
                    ans[i]++;
                num[maxn+sum]++;
            }
            sum=0;
            for(int j=i+1;j<=n;j++)
            {
                if(a[j]>a[i])
                    sum++;
                else
                    sum--;
                if(sum==0)//他的左区间比他大的数和比它小的数个数一样,它直接能够是中位数
                    ans[i]++;
                ans[i]+=num[maxn-sum];//加上左边数量对应的数目
            }
        }
        for(int i=1;i<n;i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41292370/article/details/85206636