题目地址:Ural 1303
先按每一个线段的左端点排序,然后设置一个起点s。每次都从起点小于等于s的线段中找到一个右端点最大的。
并将该右端点作为新的起点s,然后继续找。
从左到右扫描一遍就可以。
代码例如以下:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
#define LL __int64
const int INF=0x3f3f3f3f;
int a[100000];
struct node
{
int l, r, ll, rr;
} fei[100000];
int cmp(node x, node y)
{
return x.l<y.l;
}
int main()
{
int m, i, j, n, l, r, s, max1, cnt=0, tot, pos, flag, flag1, ll, rr;
scanf("%d",&m);
while(scanf("%d%d",&ll, &rr)!=EOF&&(ll||rr))
{
if(rr<=0||ll>=m) continue ;
fei[cnt].ll=ll;
fei[cnt].rr=rr;
l=ll;r=rr;
if(l<0)
l=0;
if(r>m)
r=m;
fei[cnt].l=l;
fei[cnt++].r=r;
}
sort(fei,fei+cnt,cmp);
s=0;
tot=0;
if(cnt==0)
{
printf("No solution\n");
}
else
{
for(i=0; i<cnt;)
{
max1=-1;
flag=0;
while(fei[i].l<=s&&i<cnt)
{
flag=1;
if(max1<fei[i].r)
{
max1=fei[i].r;
pos=i;
}
i++;
}
if(!flag)
break;
if(s<max1)
{
a[tot++]=pos;
s=max1;
}
}
if(i<cnt||s<m)
puts("No solution");
else
{
printf("%d\n",tot);
for(i=0; i<tot; i++)
{
printf("%d %d\n",fei[a[i]].ll,fei[a[i]].rr);
}
}
}
return 0;
}