离散化板子

35 篇文章 0 订阅

题目大概意思是给定一个大区间(起点为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;//得出数据的对应排名

    }
    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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值