1.[CQOI2009]中位数图
题目描述
给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。
输入描述:
第一行为两个正整数n和b ,第二行为1~n 的排列。
输出描述:
输出一个整数,即中位数为b的连续子序列个数。
示例1
输入
复制
7 4
5 7 2 4 3 1 6
输出
复制
4
备注:
对于30%的数据中,满足 n \le 100n≤100;
对于60%的数据中,满足 n \le 1000n≤1000;
对于100%的数据中,满足 n \le 100000,1 \le b \le nn≤100000,1≤b≤n。
思路:注意题目上说的奇数连续子序列包括1个,只取它自己;找中位数,就是要取出的序列排序后它刚好在最中间,我们可以忽略具体数值,将比中位数大的数存为1,比它小的存为-1,因为是序列,无重复数据,再记录下中位数的位置,求出后缀和,前缀和;取出的子序列有三种情况,中位数向左取或向右取,或者两边都含有,前缀和为零+后缀和为零+(前缀和+后缀和=0)就是符合要求的子序列;
AC代码:
#include <iostream>
using namespace std;
int a[100001],num[100001];
int main()
{
int n,b,c,k;
cin>>n>>b;
for(int i=1;i<=n;i++)
{
cin>>c;
if(c<b)
a[i]=-1;
else if(c==b)
k=i;
else a[i]=1;
}
int sum=0,count=0;
for(int i=k-1;i>0;i--)
{
sum+=a[i];
num[i]=sum;
if(sum==0)
count++;
}
sum=0;
for(int i=k+1;i<=n;i++)
{
sum+=a[i];
num[i]=sum;
if(sum==0)
count++;
for(int j=k-1;j>0;j--)
if(num[i]+num[j]==0)
count++;
}
cout<<count+1;
return 0;
}
2. 货物种类
题目描述
某电商平台有n个仓库,编号从1到n。
当购进某种货物的时候,商家会把货物分散的放在编号相邻的几个仓库中。
我们暂时不考虑售出,你是否能知道,当所有货物购买完毕,存放货物种类最多的仓库编号为多少?
输入描述:
在第一行中给出两个正整数n,m,1≤n,m≤105n, m, 1\le n, m \le 10^5n,m,1≤n,m≤105,分别代表仓库的数目和进货的次数。
接下来 m 行,每行三个正整数l,r,d,1≤l,r≤n,1≤d≤109l,r,d,1 \le l,r \le n, 1 \le d \le 10^9l,r,d,1≤l,r≤n,1≤d≤109。编号在l和r之间的仓库收进编号为d的货物。
(包括l和r)
输出描述:
在一行中输出存放货物种类最多的仓库编号,若满足条件的仓库不止一个,则输出编号最小的那个。
示例1
输入
5 5 1 1 1 3 3 1 2 5 2 5 5 1 4 5 1
输出
3
思路:本来想暴力一点,用每输入一组区间和货物就给区间赋相应的货物编号;但是出现问题,重复时就有问题像1 3 1;2 3 2;3 3 1;就不对了;后来用结构体储存区间左右端点和货物编号,然后对货物编号相同的数据按区间排序,遍历合并区间统计区间内货物种类
#include<iostream>
#include<algorithm>
using namespace std;
int b[100001];
struct f
{
int l,r,d;
}s[100001];
bool comp(f a,f b)
{
if(a.d==b.d) return a.l<b.l;
return a.d<b.d;
}
int main()
{
int n,m;
cin>>n>>m;
for(int j=1;j<=m;j++)
{
cin>>s[j].l>>s[j].r>>s[j].d;
}
sort(s+1,s+m+1,comp);
int row=s[1].r,le=s[1].l;
for(int i=2;i<=m;i++)
{
if(row>=s[i].l&&s[i].d==s[i-1].d)
{
row=max(row,s[i].r);
}else
{
b[le]++,b[row+1]--;row=s[i].r,le=s[i].l;
}
}
b[le]++;b[row+1]--;
int maxn=0,sum=0,k;
for(int i=1;i<=n;i++)
{
sum+=b[i];
//cout<<sum<<" ";
if(sum>maxn)
{
maxn=sum;
k=i;
}
}
cout<<k;
return 0;
}