您的位置:首页 > 其它

HDU 5701:中位数计数

2017-11-27 14:57 351 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5701

这题n方可过,显然满足条件的区间必是含奇数个数的区间,对于每个数,

先往右扫一遍,求得其右边比其大的和比其小的数的个数的差x,然后再往

左扫一遍,求其左边比起小的数和比起大的数的差,若一个数在这个区间为

中位数,则若其右边比它大的比比它小的多x(有点绕),则其左边相反小的要

比大的多x,这样x才能正好在中间位置,用一个数组记录一下差值为某个数

的个数即可,注意要算上这个数自己。

#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

int const maxn = 8005;
int const con = 8002;
int num[maxn],vis[maxn*2];
int main() {
int n,cnt,ans;
while(~scanf("%d",&n)) {
for(int i = 1; i <= n; i++) {
scanf("%d",&num[i]);
}
for(int i = 1; i <= n; i++) {
cnt = 0;
ans = 0;
memset(vis,0,sizeof(vis));
vis[con]++; ///统计上自己
//求第i个数右侧比i大-比i小的的差
for(int j = i+1; j <= n; j++) {
if(num[j]>num[i])
cnt++;
else
cnt--;
vis[con+cnt]++; ///由于cnt可能是负数,所以给它加上一个比较大的数
}
ans += vis[con]; ///加上自己本身这个答案
cnt = 0;
for(int j = i-1; j > 0; j--) {
if(num[j]<num[i])
cnt++;
else
cnt--;
ans += vis[con+cnt];
}
if(i != n)
printf("%d ",ans);
else
printf("%d\n",ans);

}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: