复制
收藏
提问
简洁
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数 轴上的每个整数点,即0,1,2,……,L,都种有一棵树。 由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已 知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树 都移走后,马路上还有多少棵树。 【输入形式】 输入文件的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点 和终止点的坐标。 【输出形式】 输出文件包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。 【样例输入】 500 3 150 300 100 200 470 471 【样例输出】 298 【提示】 数据规模和约定 对于20%的数据,区域之间没有重合的部分; 对于其它的数据,区域之间有重合的情况。 C++
3月前
全网
文档
学术
百科
知识库
回答简洁模式
深入研究一些
这个问题是一个典型的区间合并问题,可以通过线段树或者排序加扫描线的方法来解决。下面我将提供一个基于排序加扫描线的C++解决方案。
首先,我们需要读取输入文件中的数据,包括马路的长度 和区域的数目 ,以及每个区域的起始点和终止点坐标。接着,我们将所有区域按照起始点进行排序,以便能够按照顺序处理它们。
在处理每个区域时,我们需要记录下每个区域的起始点和终止点,以及它们是否已经被考虑过。如果一个区域的终止点小于或等于前一个区域的终止点,那么这个区域实际上已经被前一个区域覆盖,不需要再次考虑。
最后,我们将计算出所有未被覆盖的树的总数,即原始的树的总数减去所有区域覆盖的树的总数。以下是这个问题的C++代码实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Range {
int start, end;
bool considered;
};
int main() {
int L, M;
cin >> L >> M;
vector<Range> ranges(M);
for (int i = 0; i < M; ++i) {
cin >> ranges[i].start >> ranges[i].end;
ranges[i].considered = false;
}
// Sort the ranges by the start point
sort(ranges.begin(), ranges.end(), [](const Range &a, const Range &b) {
return a.start < b.start;
});
int totalTrees = L + 1; // Including the tree at position 0
int currentEnd = 0;
for (int i = 0; i < M; ++i) {
if (!ranges[i].considered) {
if (ranges[i].start > currentEnd) {
// No overlap, just update the current end
currentEnd = ranges[i].end;
} else {
// There is an overlap, find the new end
currentEnd = max(currentEnd, ranges[i].end);
}
totalTrees -= currentEnd - ranges[i].start + 1;
ranges[i].considered = true;
}
}
cout << totalTrees << endl;
return 0;
}
这段代码首先定义了一个结构体 Range
来存储每个区域的起始点和终止点,以及一个标记位来表示该区域是否已经被考虑过。然后,代码读取输入数据,并对区域按照起始点进行排序。接着,代码遍历排序后的区域列表,计算出未被覆盖的树的总数,并输出结果。79
你觉得结果怎么样?