HDU 5124 lines

lines

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1650    Accepted Submission(s): 684


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(1T100)(the data for N>100 less than 11 cases),indicating the number of test cases.
Each test case begins with an integer N(1N105),indicating the number of lines.
Next N lines contains two integers Xi and Yi(1XiYi109),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
 
Source

 

Recommend
heyang
 
 

 BC官方题解:

我们可以将一条线段 [xi,yi] 分为两个端点 xi 和 (yi)+1 ,在 xi 时该点会新加入一条线段,同样的,在 (yi)+1 时该点会减少一条线段,因此对于2n个端点进行排序,令 xi 为价值1, yi 为价值-1,问题转化成了最大区间和,因为1一定在-1之前,因此问题变成最大前缀和,我们寻找最大值就是答案,另外的,这题可以用离散化后线段树来做。复杂度为排序的复杂度即 nlgn ,另外如果用第一种做法数组应是2n,而不是n,由于各种非确定性因素我在小数据就已经设了n=10W的点。

 

用第一种最大前缀和的方法,需要注意对于坐标相同的点要一次性累加完,或者先将-1的点累加。

一次性累加完(for循环)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <map>
 4 #include <vector>
 5 #include <functional>
 6 #include <string>
 7 #include <cstring>
 8 #include <queue>
 9 #include <stack>
10 #include <set>
11 #include <cmath>
12 #include <cstdio>
13 using namespace std;
14 
15 #define IOS ios_base::sync_with_stdio(false)
16 #define TIE std::cin.tie(0)
17 typedef long long LL;
18 typedef unsigned long long ULL;
19 const int INF=0x3f3f3f3f;
20 const double PI=4.0*atan(1.0);
21 const int MAX_N=200005;
22 typedef struct point{
23     int x,flag;
24 }P;
25 P a[MAX_N];
26 bool cmp(const P &a,const P &b){ return a.x<b.x;}
27 int main()
28 {
29     int t,n,cnt,x,y;
30     long long sum,ma;
31     scanf("%d",&t);
32     while(t--){
33         scanf("%d",&n);
34         cnt=0;
35         for(int i=0;i<n;i++){
36             scanf("%d%d",&x,&y);
37             a[cnt].x=x; a[cnt++].flag=1;
38             a[cnt].x=y+1; a[cnt++].flag=-1;
39         }
40         sort(a,a+cnt,cmp);
41         ma=sum=0;
42         for(int i=0;i<cnt;){
43             int j=i;
44             for(;a[j].x==a[i].x&&j<cnt;j++){
45                 sum+=a[j].flag;
46             }
47             i=j;
48             if(sum>ma) ma=sum;
49         }
50         printf("%d\n",ma);
51     }
52 }
View Code

 

先将-1的点累加 cmp函数中实现

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <map>
 4 #include <vector>
 5 #include <functional>
 6 #include <string>
 7 #include <cstring>
 8 #include <queue>
 9 #include <stack>
10 #include <set>
11 #include <cmath>
12 #include <cstdio>
13 using namespace std;
14 #define IOS ios_base::sync_with_stdio(false)
15 #define TIE std::cin.tie(0)
16 typedef long long LL;
17 typedef unsigned long long ULL;
18 const int INF=0x3f3f3f3f;
19 const double PI=4.0*atan(1.0);
20 
21 const int MAX_N=200005;
22 typedef struct point{
23     int x,flag;
24 }P;
25 P a[MAX_N];
26 bool cmp(const P &a,const P &b){ return a.x<b.x||(a.x==b.x&&a.flag<b.flag);}
27 int main()
28 {
29     int t,n,cnt,x,y;
30     long long sum,ma;
31     scanf("%d",&t);
32     while(t--){
33         scanf("%d",&n);
34         cnt=0;
35         for(int i=0;i<n;i++){
36             scanf("%d%d",&x,&y);
37             a[2*i].x=x; a[2*i].flag=1;
38             a[2*i+1].x=y+1; a[2*i+1].flag=-1;
39         }
40         sort(a,a+2*n,cmp);
41         ma=sum=0;
42         for(int i=0;i<2*n;i++){
43             sum+=a[i].flag;
44             if(sum>ma) ma=sum;
45         }
46         printf("%d\n",ma);
47     }
48 }
View Code

 

posted @ 2016-08-01 18:47  Cumulonimbus  阅读(175)  评论(0编辑  收藏  举报