1. 程式人生 > >【5701 HDU】中位數計數(思維)

【5701 HDU】中位數計數(思維)

Problem  Description:

中位數定義為所有值從小到大排序後排在正中間的那個數,如果值有偶數個,通常取最中間的兩個數值的平均數作為中位數。

現在有n個數,每個數都是獨一無二的,求出每個數在多少個包含其的區間中是中位數。

Input:

多組測試資料

第一行一個數n(n≤8000)

第二行n個數,0≤每個數≤109,

Output:

N個數,依次表示第i個數在多少包含其的區間中是中位數。

Sample  Input:

5 1 2 3 4 5

Sample  Output:

1 2 3 2 1

思路:因為題上說n個數,每個數都是獨一無二的,因此,要想讓第i個數是中位數,則區間中數的個數必須是奇數個;並且判斷一個數在區間中是中位數的條件是左邊比它大的數的個數和右邊比它小的數的個數要一樣多(或者左邊比它小的數的個數和右邊比它大的數的個數一樣多),要注意題上說的是包含它的區間。

所以我們可以用一個數組 cnt[8005*2] 標記它在每個區間中是中位數的情況有幾種,然後把每個區間的每種情況加在一起,輸出答案。

My  DaiMa:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int maxn = 8005;
int main()
{
    int n,a[8005],cnt[16010];
    while(~scanf("%d",&n))
    {
        for(int i = 0; i < n; i++)
            cin >> a[i];
        for(int i =0; i < n; i++)
        {
            memset(cnt,0,sizeof(cnt));
            int ans = 0,flag = 0;
            cnt[maxn]++;
            for(int j = i+1; j <n; j++)
            {
                if(a[j] > a[i]) flag ++;
                else flag--;
                cnt[maxn+flag]++;
            }
            ans = cnt[maxn];
            flag = 0;
            for(int k = i-1; k >= 0; k--)
            {
                if(a[k] > a[i]) flag ++;
                else flag --;
                ans += cnt[maxn-flag];
            }
            if(i < n-1)
                printf("%d ",ans);
            else
                printf("%d\n",ans);
        }
    }
}