http://codeforces.com/contest/612/problem/D
【题解】
http://blog.csdn.net/strokess/article/details/52248062
【题意】
在数轴x上,给定n个线段和一个值k,问被这n条线段覆盖了至少k次的区间有多少个,输出每一个。
【思路】
扫描线思想。把这n个线段的左右端点放在一起从小到大排序,用cnt记录当前区间被覆盖了多少次,遇到左端点cnt++,遇到右端点cnt--,当cnt==k时记录这时的左端点和右端点。
当左端点和右端点相等时先考虑左端点再考虑右端点,具体为什么可以考虑第二个样例。
因此我们可以很方便地用pair实现这一点,用0标记左端点,用1标记右端点。pair默认排序按first优先,second其次。
【Accepted】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<vector> 7 #include<utility> 8 9 using namespace std; 10 const int maxn=1e6+3; 11 typedef long long ll; 12 const ll mod=1e9+7; 13 14 vector<pair<int,int> > v; 15 vector<int> ans; 16 int n,k; 17 int main() 18 { 19 while(~scanf("%d%d",&n,&k)) 20 { 21 v.clear(); 22 ans.clear(); 23 for(int i=0;i<n;i++) 24 { 25 int x,y; 26 scanf("%d%d",&x,&y); 27 v.push_back(make_pair(x,0)); 28 v.push_back(make_pair(y,1)); 29 } 30 sort(v.begin(),v.end()); 31 int sz=v.size(); 32 int cnt=0; 33 for(int i=0;i<sz;i++) 34 { 35 // cout<<v[i].first<<" "<<v[i].second<<endl; 36 if(v[i].second==0) 37 { 38 cnt++; 39 if(cnt==k) 40 { 41 ans.push_back(v[i].first); 42 } 43 } 44 else 45 { 46 if(cnt==k) 47 { 48 ans.push_back(v[i].first); 49 } 50 cnt--; 51 } 52 } 53 printf("%d ",ans.size()/2); 54 for(int i=0;i<ans.size()/2;i++) 55 { 56 printf("%d %d ",ans[2*i],ans[2*i+1]); 57 } 58 } 59 return 0; 60 }