[CQOI2009]中位数图(前后缀和(转换思想))
链接:https://ac.nowcoder.com/acm/problem/19913链接:https://ac.nowcoder.com/acm/problem/19913
给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。
#include<iostream>
using namespace std;
int n,b;
int a[100010];
int sum[100010];
int main()
{
int pos;
cin>>n>>b;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]>b)
a[i]=1;
else if(a[i]<b)
a[i]=-1;
else if(a[i]==b)
{
a[i]=0;
pos=i;
}
sum[i]=sum[i-1]+a[i];
}
int cnt=0;
for(int i=pos;i<n;i++)
for(int j=pos;j>=0;j--)
{
if(sum[i]-sum[pos]==sum[j-1]-sum[pos])//后缀和 前缀和
cnt++;
}
cout<<cnt<<endl;//包括自己本生(一个数也有中位数)
return 0;
}
先将这一串数转换一下:比中位数大的记为1,比中位数小的记为-1,中位数本身记为0
若满足条件,转换后的这一串数相加肯定0(满足这一条件肯定为奇数个数,不用再写程序筛选奇数个数)
从0处往前求后缀和,往后求前缀和,当前后缀和互为相反数的时候,满足题意。
算法入门基础 文章被收录于专栏
Dawn的算法入门