题目:
数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
不可能办到输出-1
Input:
第一行:N和T
第二行至N+1行: 每一行一个闭区间。
Output:
选择的区间的数目,不可能办到输出-1
Examples:
Input
3 10
1 7
3 6
6 10
Output
2
hint:
这道题输入数据很多,请用scanf而不是cin
思路:
该题的贪心策略是:每次选择的区间是包括当前起点的终点数字最大的区间。
把各区间按照be从小到大排序。如果区间1的起点不小于等于1,则无解,否则选择起点在包括1的终点数字最大的区间。选择此区间[1,tempend] 后,新的起点应该设置为tempend+1 ,并再次寻找包括tempend+1的终点数字最大的区间。如此重复,直到tempend>=t或者没有可用的区间为止。
注意:
覆盖整点,即(1,2)和(3,4)可以覆盖(1,4),每次更新目标区间起点时应为上一次所选区间终点+1。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
struct zone
{
int be;
int end;
};
bool cmp(zone a, zone b)
{
return a.be < b.be;
}
int main()
{
int count, n, t;
while (scanf("%d %d",&n,&t)!= EOF)
{
count = 0;
zone *temp = new zone[n];
for (int i = 0; i < n; i++)
scanf("%d %d", &temp[i].be, &temp[i].end);
sort(temp, temp + n, cmp);
int tempbe = 0, tempend = 0, index = 0;
while (tempend < t)
{
tempbe = tempend + 1;
for (int i = index; i < n; i++)
{
if (temp[i].be <= tempbe)
{
tempend = max(temp[i].end, tempend);
}
else
{
index = i;
break;
}
}
if (tempbe <= tempend)
count++;
else
break;
}
if (tempend >= t)
cout << count << endl;
else
cout << "-1" << endl;
}
return 0;
}