Problem Description:
John has several lines. The lines are covered on the X axis. Let A is a point which is covered by the most lines. John wants to know how many lines cover A.
Input:
The first line contains a single integer T(1≤T≤100)(the data for N>100 less than 11 cases),indicating the number of test cases.
Each test case begins with an integer N(1≤N≤105),indicating the number of lines.
Next N lines contains two integers Xi and Yi(1≤Xi≤Yi≤109),describing a line.
Each test case begins with an integer N(1≤N≤105),indicating the number of lines.
Next N lines contains two integers Xi and Yi(1≤Xi≤Yi≤109),describing a line.
Output:
For each case, output an integer means how many lines cover A.
Sample Input:
2
5
1 2
2 2
2 4
3 4
5 1000
5
1 1
2 2
3 3
4 4
5 5
Sample Output:
3
1
题意:给出n条线段,输出这些线段覆盖的某个点的最多个数,也就是找到一个点出现在这些线段的次数最多,输出这个点出现的次数。
分析:由于这些区间的端点的值会很大,显然直接数组模拟是不对的(存不下啊!),所以我们需要稍微离散化一下,离散化完之后又用到之前学的区间左端点加1,右端点的下一位减1,这样来求区间点出现次数的最大值是最节省时间的(简单说一下原理:一开始vis标记数组初始化是为0的,设左端点为l,右端点为r,那么vis[l]++,vis[r+1]--,这样的话l~r之间都是vis++的,当出现vis[r+1]--时说明下次的区间是没有l~r的,需要将这些值减掉。。。。不知道这样讲清楚不清楚,不过这道题让我更明白了这个算法)。
#include<stdio.h> #include<string.h> #include<queue> #include<math.h> #include<stdlib.h> #include<algorithm> using namespace std; const int N=1e6+10; const int INF=0x3f3f3f3f; const int MOD=1e9+7; typedef long long LL; int a[N], b[N]; int c[N]; int vis[N]; int main () { int T, n, i; scanf("%d", &T); while (T--) { scanf("%d", &n); memset(vis, 0, sizeof(vis)); for (i = 0; i < n; i++) { scanf("%d%d", &a[i], &b[i]); c[i] = a[i]; c[i+n] = b[i]; } sort(c, c+2*n); for (i = 0; i < n; i++) { int indexa = lower_bound(c, c+2*n, a[i]) - c; ///在c数组中找到第一个>=a[i]的位置(该位置就是离散化后的a[i]) int indexb = lower_bound(c, c+2*n, b[i]) - c; vis[indexa]++; vis[indexb+1]--; } int ans = 0, Max = -INF; for (i = 0; i < 2*n; i++) { ans += vis[i]; if (ans > Max) Max = ans; } printf("%d ", Max); } return 0; }