I good vegetable a!

要对青春说再见了。。。

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

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

【分析&解题思路】

首先对于第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;
}


阅读更多
版权声明:蒟蒻博客,请随意转载。 https://blog.csdn.net/just_sort/article/details/51558150
个人分类: ACM/ICPC_HDOJ
上一篇HDU 5710 Digit-Sum
下一篇西南科技大学 信息工程学院 院赛 部分题题解,持续更新.
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭