2023-10-30-LearningRecord
刷题Day002
题目一
[NOIP2005 普及组] 校门外的树
题目描述
某校大门外长度为 的马路上有一排树,每两棵相邻的树之间的间隔都是 米。我们可以把马路看成一个数轴,马路的一端在数轴 的位置,另一端在 的位置;数轴上的每个整数点,即 ,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入格式
第一行有两个整数,分别表示马路的长度 和区域的数目 。
接下来 行,每行两个整数 ,表示一个区域的起始点和终止点的坐标。
输出格式
输出一行一个整数,表示将这些树都移走后,马路上剩余的树木数量。
样例 #1
样例输入 #1
1 2 3 4
| 500 3 150 300 100 200 470 471
|
样例输出 #1
提示
【数据范围】
- 对于 的数据,保证区域之间没有重合的部分。
- 对于 的数据,保证 ,,。
【题目来源】
NOIP 2005 普及组第二题
解法一(状态数组):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vector> using namespace std;
struct Volume { int startPoint; int endPoint; };
int collectInput(vector<Volume>& volume) { int Length, areaAccount, leftPoint, rightPoint; scanf("%d %d", &Length, &areaAccount); Volume temp; for (int i = 0; i < areaAccount; i++) { scanf("\n%d %d", &leftPoint, &rightPoint); temp.startPoint = leftPoint; temp.endPoint = rightPoint; volume.push_back(temp); } return Length + 1; }
int main() { vector<Volume> volume; vector<bool> statusArray; int Length = collectInput(volume);
statusArray.resize(Length,true); for (int i = 0; i < volume.size(); i++) { for (int j = volume[i].startPoint; j <= volume[i].endPoint; j++) { statusArray[j] = false; } } int count = 0; for (int i = 0; i < statusArray.size(); i++) { if (statusArray[i]) { count++; } continue; } cout << count;
return 0; }
|
解法二(线段树):
前置知识:[前缀和]前缀和
