来源:NOIP黑龙江模拟赛
代码提交:https://qdacm.com/P/2834
可以翻阅下我的那篇前缀和概述,有惊喜
题目描述:
201781喜欢区间和平面,他有N个一维区间[xi,yi](1<=i<=N)和一个左上角座标为(1,1)的二维平面(平面无限大)。
201781 的好奇心驱使,他想知道把这N个区间 无重叠的(左右端点也算重叠)放到二维平面上最少需要多少行?
每一个区间只能出现在一行中,不能跨行。
输入格式
第一行是一个整数 N,代表区间的数目。
之后 N行,第 i + 1 行有两个整数 xi, yi。其中 xi 和 yi 表示第i 个区间需要的范围。
输出格式
输出一个正整数,表示最少需要占用的行的个数。
思路:如果题目没有限制条件区间不可重叠的话,那么我们就cout<< 1 << endl;别痴想妄想了,这可是B题呢。
那么题目说最少占用行数,也就是每行的区间我要尽可能的利用。换个idea,我对每段区间[L,R],a[L] = 1.a[R+1] = -1.如果一段区间k内的前缀和为10,说明在区间k中有10个区间a1,a2.....a10.那么我就必须开10行,来把这些重叠在一起的区间分到每一行去。据此,我只需要记录区间内出现的最大前缀和ans,即为最小行数。(因为这个最大前缀和ans说明我最少需要开ans行,才能满足题目条件)
代码如下:
#include <iostream>
#include <cstdio>
#include <cmath>
#define N 1000010
using namespace std;
int mp[N];
int main(){
int n ,ans = 0 ;
cin >> n;
for(int i = 0 ; i < n ; i++){
int l,r;
scanf("%d%d",&l,&r);
mp[l] += 1;
mp[r+1] -= 1;
}
int M = 0;
for(int i = 0 ; i < N;i++){
M +=mp[i];
ans = max(M,ans);
}
cout << ans <<endl;
}