欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

离散化板子

程序员文章站 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;
}
相关标签: 离散化 离散化