C++——NOIP模拟题——中位数
2017-04-29 14:57
435 查看
题目描述
有一个长度为 N 的数列{A1,A2,…,AN},这个 N 个数字恰好是 1..N 的一个排列。你需要统计有多少个子序列{Ai,Ai+1,…,Aj}满足:i≤j 且 j-i+1 为奇数,序列的中位数为 B。例如{5,1,3}的中位数为 3 。
输入格式
第一行包含两个正整数 N 和 B ;第二行包含 N 个整数,第 i 个整数为 Ai。
输出格式
输出仅包含一个整数,为满足条件的子序列的个数。
样例数据 1
输入7 4
5 7 2 4 3 1 6
输出
4
备注
【数据范围】对于 30% 的数据,满足:N≤100;
对于 60% 的数据,满足:N≤1000;
对于 100% 的数据,满足:N≤100000;1≤B≤N。
解题报告:
简单扫描。
首先,因为中位数是B且序列长度为奇数,那么这个子序列必然要包含B这个数字。接下来我们将小于B的数字看成-1,大于B的数字看成1,B看成是O。从B所在位置开始向左扫描,统计i的个数L[i];同理,向右扫描统计R[i]。最终的答案就为:∑L[i]*R[-i]。
时间效率:O(N); 空间效率:O(N)。
#include<iostream>
#include<cstdio>
int a[100001],ll[200001],rr[200001],n,b,num,ans;
inline int readint()
{
int i=0,f=1;
char ch;
for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
for(;ch>='0' && ch<='9';ch=getchar())
i=(i<<3)+(i<<1)+ch-'0';
return i*f;
}
int main()
{
register int i,j;
n=readint();
b=readint();
for(i=1;i<=n;++i)
{
a[i]=readint();
if(a[i]==b)
{
num=i;
a[i]=0;
}
else if(a[i]>b) a[i]=1;
else a[i]=-1;
}
auto int l,r;
l=r=n;
for(i=num;i>0;--i)
{
l+=a[i];
++ll[l];
}
for(i=num;i<=n;++i)
{
r+=a[i];
++rr[r];
}
int len=2*n;
for(i=0;i<=len;++i) ans+=(ll[i]*rr[len-i]);
printf("%d\n",ans);
return 0;
}
var n,b,num,ans,i,l,r,len,p:longint; ll,rr:array [0..200000] of longint; a:array [0..100000] of longint; begin read(n,b); for i:=1 to n do begin read(p); if p=b then num:=i; if p>b then a[i]:=1; if p<b then a[i]:=-1; end; l:=n; r:=n; for i:=num downto 1 do begin l:=l+a[i]; ll[l]:=ll[l]+1; end; for i:=num to n do begin r:=r+a[i]; rr[r]:=rr[r]+1; end; len:=2*n; for i:=0 to len do ans:=ans+(ll[i]*rr[len-i]); write(ans); end.
相关文章推荐
- C++——NOIP模拟题——葫芦
- C++——NOIP模拟题——number
- 【NOIP 模拟题】中位数(规律+递推)
- Pascal & C++——NOIP模拟题——小X学游泳
- C++——NOIP模拟题——保留道路
- C++——NOIP模拟题——wild
- C++——NOIP模拟题——tree
- C++——NOIP模拟题——减法
- C++——NOIP模拟题——牧场的安排
- C++——NOIP模拟题——方阵
- C++——NOIP模拟题——病毒
- C++——NOIP模拟题——零件加工
- C++——NOIP模拟题——列车调度
- C++——NOIP模拟题——单词的安全性
- C++——NOIP模拟题——猴子
- NOIP模拟题 2016.10.29 [DP] [中位数相关] [折半搜索]
- C++——NOIP模拟题——动态分班
- C++——NOIP模拟题——二叉树
- C++——NOIP模拟题——装果子
- 【noip模拟题】迎接仪式(dp+特殊的技巧)