大意:数轴上有n个闭区间[ai,bi],选择尽量少的区间覆盖一条指定的线段[s,t]。
思路:贪心,具体见刘汝佳白书P154。把各区间按照a从小到大排序。如果区间1的起点不是s,无解,否则选择起点在s的最长区间。选择此区间[ai,bi]后,新的起点设置为bi,然后经过依次扫描之后就可以得出最小的线段数。并用另一个结构体储存路径。
另外:排序可有可无,有了只不过是一种优化措施,没有排序的话程序也对,最主要的算法还是贪心。
CODE:
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
#define MAXN 100010
struct node
{
int l;
int r;
}a[MAXN] , path[MAXN];
int cmp(const node &a, const node &b)
{
if(a.l != b.l) return a.l < b.l;
else return a.r > b.r; //这里不影响程序的正确性
}
int n, m;
void init()
{
memset(a, 0, sizeof(a));
memset(path, 0, sizeof(path));
}
void solve()
{
int flag, pos;
int Max = 0, tot = 0, ans = 0, left = 0;
sort(a, a+n, cmp); //排序,
for(;;)
{
if(left >= m) break;
Max = flag = 0;
for(int i = 0; i < n; i++)
{
if(a[i].l <= left)
{
if(a[i].r > Max)
{
pos = i;
Max = a[i].r;
flag = 1;
} //找最右边的区间
}
}
if(flag)
{
ans++;
left = Max; //更新最大区间
path[tot++] = a[pos];
}
else break;
}
if(flag)
{
printf("%d\n", tot);
for(int i = 0; i < tot; i++)
{
printf("%d %d\n", path[i].l, path[i].r);
}
}
else printf("0\n");
}
int main()
{
int T;
scanf("%d%*c", &T);
while(T--)
{
init();
int i = 0;
int x, y;
scanf("%d", &m);
while(scanf("%d%d", &x, &y))
{
if(!x && !y) break;
a[i].l = x, a[i].r = y;
i++;
}
n = i;
solve();
if(T) printf("\n");
}
return 0;
}
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
#define MAXN 100010
struct node
{
int l;
int r;
}a[MAXN] , path[MAXN];
int cmp(const node &a, const node &b)
{
if(a.l != b.l) return a.l < b.l;
else return a.r > b.r; //这里不影响程序的正确性
}
int n, m;
void init()
{
memset(a, 0, sizeof(a));
memset(path, 0, sizeof(path));
}
void solve()
{
int flag, pos;
int Max = 0, tot = 0, ans = 0, left = 0;
sort(a, a+n, cmp); //排序,
for(;;)
{
if(left >= m) break;
Max = flag = 0;
for(int i = 0; i < n; i++)
{
if(a[i].l <= left)
{
if(a[i].r > Max)
{
pos = i;
Max = a[i].r;
flag = 1;
} //找最右边的区间
}
}
if(flag)
{
ans++;
left = Max; //更新最大区间
path[tot++] = a[pos];
}
else break;
}
if(flag)
{
printf("%d\n", tot);
for(int i = 0; i < tot; i++)
{
printf("%d %d\n", path[i].l, path[i].r);
}
}
else printf("0\n");
}
int main()
{
int T;
scanf("%d%*c", &T);
while(T--)
{
init();
int i = 0;
int x, y;
scanf("%d", &m);
while(scanf("%d%d", &x, &y))
{
if(!x && !y) break;
a[i].l = x, a[i].r = y;
i++;
}
n = i;
solve();
if(T) printf("\n");
}
return 0;
}