HDU 5701 中位数计数 (百度之星初赛)

来源:互联网 发布:淘宝whoo小样是真的吗 编辑:程序博客网 时间:2024/05/21 08:52

【题目链接】点击打开链接

【分析&解题思路】

首先对于第i个数,我们从i-1个数开始递减,分别与第i个数进行比较,假设比第i个数大的数的个数即为l,比第i个数小的数的个数即为r,dp[l-r=k]则为[比第i个数的数的个数][比第i个数的数的个数]多k个的区间个数,那要保证第i个数是区间内的中位数,我只需要在第i个数的右边找有多少个[比第i个数的数的个数][比第i个数的数的个数]多k个的区间,这样两个区间连接起来,正好[比第i个数的数的个数][比第i个数的数的个数]一样多,这样,第i个数就是此区间内的中位数

另外,因为数组下标必须为非负整数,故把数组的中心点移至8000,即dp[8000+k],这样就保证了下标一定是符合要求的

【AC代码】

#include<stdio.h>#include<iostream>#include<algorithm>#include<string>#include<string.h>#include<math.h>#include<vector>#include<queue>#include<stack>#include<map>#include<set>typedef __int64 LL;typedef unsigned __int64 LLU;const int nn=110000;const int inf=0x3fffffff;const int mod=1000000007;const LL inf64=(LL)inf*inf;const double eps = 1e-12;using namespace std;int n;int a[8100];int ans[8100];int tem[8100*2];int main(){    int i,j;    while(scanf("%d%",&n)!=EOF)    {        for(i=1;i<=n;i++)        {            scanf("%d",&a[i]);            ans[i]=1;        }        for(i=1;i<=n;i++)        {            memset(tem,0,sizeof(tem));            int ix=0;            for(j=i-1;j>=1;j--)            {                if(a[j]<a[i])                {                    ix--;                }                else                    ix++;                tem[ix+8010]++;                if(ix==0)                    ans[i]++;            }            ix=0;            for(j=i+1;j<=n;j++)            {                if(a[j]<a[i])                    ix--;                else                    ix++;                ans[i]+=tem[8010-ix];                if(ix==0)                    ans[i]++;            }        }        for(i=1;i<=n;i++)        {            printf("%d%c",ans[i],i==n?'\n':' ');        }    }    return 0;}


0 0
原创粉丝点击