这道题要学一下重载运算符 思路就是如果先按右端点排序 区间有点就过 无点 就加点在区间右端点
[905区间选点] [c++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include<bits/stdc++.h> using namespace std; const int N=100010; int n; struct Range { int l,r; bool operator < (const Range &w) const { return r<w.r; } }range[N]; int main() { cin>>n; for(int i=0;i<n;i++) { int l,r; cin>>l>>r; range[i]={l,r}; } sort(range,range+n); int res=0,ed=-2e9; for(int i=0;i<n;i++) { if(range[i].l>ed) { res++; ed=range[i].r; } } cout<<res<<endl; return 0; }
区间分组这道题可以用求最大区间厚度的思想
[区间分组] [c++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #include <iostream> #include <algorithm> using namespace std; const int N = 100100; int n; int b[2 * N], idx; int main() { scanf ("%d", &n); for(int i = 0; i < n; i ++) { int l, r; scanf("%d %d", &l, &r); b[idx ++] = l * 2;//标记左端点为偶数。 b[idx ++] = r * 2 + 1;// 标记右端点为奇数。 } sort(b, b + idx); int res = 1, t = 0; for(int i = 0; i < idx; i ++) { if(b[i] % 2 == 0) t ++; else t --; res = max(res, t); } printf ("%d\n", res); return 0; }1
这道题的思路就是 得出每个起点小于st的区间的右端点最大值 再将其更新为st
[区间覆盖] [c++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include<bits/stdc++.h> using namespace std; int n; int st,ed; const int N=100010; struct Range { int l,r; bool operator < (const Range &w ) const { return l<w.l; } }range[N]; int main() { bool f=false; cin>>st>>ed; cin>>n; for(int i=0;i<n;i++) { int l,r; cin>>l>>r; range[i]={l,r}; } sort(range,range+n); int res=0; for(int i=0;i<n;i++) //找每个起点在st左边的区间的右端点的最大值 { int j=i,r=-2e9; while(j<n && range[j].l<=st) { r=max(r,range[j].r); j++; } if(r<st) //如果遍历完了 右端点都比线段左端点小 说明不行 { res=-1; break; } res++; if(r>=ed) { f=true; break; } st=r; i=j-1; } if(!f) cout<<-1<<endl; else cout<<res<<endl; }
合并果子的思路很简单 就是每次都找最小的两个合并 用堆来维护
[合并果子] [c++]