离散化板子
程序员文章站
2022-05-27 15:21:57
...
题目大概意思是给定一个大区间(起点为0,终点为1e9),若干个(小于50000)小区间(包含在大区间内),问最多有多少个小区间有重合部分(端点也算)。
第一行输入n,表示有n个小区间,接下来n行输入小区间的起点和终点。
输出为1行,即最多多少个小区间有重合部分。
样例输入
4
3 5
4 8
1 2
5 10
样例输出
3
如果题目数据给的和善一点的话,我们可以用数组下标记录,最后统计这个数组中的最大值就可以了,然而,1e9貌似并不能这样做。
但是n是小于50000的,那么我们最多得到100000个数据,所以我们可以用到离散化的思想。
离散化
先讲讲什么是离散化。
就比如对于这个题来说,我们给两个小区间,[10,15],[12,16],那么我们得到四个数据,10,15,12,16,这四个数据的对应排名为1,3,2,4,那么我们就可以把这两个小区间理解为[1,3],[2,4],在不影响结果的前提下,把数据用其对应排名去代替,从而达到简化时间空间复杂度的目的。
这样我们就可以使用数组下标去记录了(因为n<=50000,那么我们只要开一个1e5+5的数组就可以了),最后统计出答案。
#include<iostream>
#include<queue>
#include<string.h>
#include<string>
#include<stdio.h>
#include<math.h>
#include<vector>
#include<algorithm>
#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
const int N=5e2+5;
const int M=1e5+5;
const int INF=0x3f3f3f3f;
int a[M],t[M],b[M];
int main()
{
int n;
cin>>n;
int cnt=0;
for(int i=1;i<=n;i++)
{
cin>>a[i*2-1];t[i*2-1]=a[i*2-1];
cin>>a[i*2];t[i*2]=a[i*2];
}
sort(t+1,t+2*n+1);
int m=unique(t+1,t+n*2+1)-(t+1);//去重函数
for(int i=1;i<=n*2;i++)
{
a[i]=lower_bound(t+1,t+m+1,a[i])-(t+1);//得出数据的对应排名
}
int maxn=0;
for(int i=1;i<=n;i++)
{
for(int j=a[i*2-1];j<=a[i*2];j++)
{
b[j]++;
maxn=max(maxn,b[j]);
}
}
cout<<maxn<<endl;
return 0;
}