区间覆盖裸题。 按照左区间端点排序,每次贪心的选取覆盖最长的那个区间。
细节参见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 1000000000;
const double eps = 1e-6;
const int maxn = 100000+5;
int T,n,m,l,r;
struct node{
int l,r;
bool operator < (const node& rhs) const {
return l < rhs.l;
}
}a[maxn];
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&m);int cnt = 0;
while(true) {
scanf("%d%d",&l,&r);
if(!l && !r) break;
if(r < 0 || l > m) continue;
if(l < 0) l = 0;
if(r > m) r = m;
a[cnt].l = l; a[cnt++].r = r;
}
sort(a,a+cnt);
int cur_l=0,len = -1, cur=0,ans = 0;
vector<node> g;
bool ok = true;
for(int i=0;i<cnt;i++) {
if(cur_l >= m) break;
if(a[i].l > cur_l && len < 0) { ok = false; break; }
else if(a[i].l > cur_l) {
cur_l += len; i--; ans++; len = -1;
g.push_back(a[cur]);
}
else {
if(len < a[i].r-cur_l) {
len = a[i].r - cur_l;
cur = i;
}
}
if(i == cnt-1 && (a[i].l <= cur_l)) {
cur_l += len;
if(cur_l < m) { ok = false; break; }
else { g.push_back(a[cur]); ans++; }
}
}
if(ok) {
printf("%d\n",ans);
for(int i=0;i<g.size();i++) printf("%d %d\n",g[i].l,g[i].r);
}
else printf("0\n");
if(T) printf("\n");
}
return 0;
}