制作不易,请多多支持!记得点个赞!👍
题目描述
某校大门外长度为 l 的马路上有一排树,每两棵相邻的树之间的间隔都是 11 米。我们可以把马路看成一个数轴,马路的一端在数轴 0 的位置,另一端在 l 的位置;数轴上的每个整数点,即 0,1,2,......,l,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
输入格式
第一行有两个整数,分别表示马路的长度 l 和区域的数目 m。
接下来 m 行,每行两个整数 u,v,表示一个区域的起始点和终止点的坐标。
输出格式
输出一行一个整数,表示将这些树都移走后,马路上剩余的树木数量。
样例 #1
样例输入 #1
500 3
150 300
100 200
470 471
样例输出 #1
298
提示
数据范围
对于 20% 的数据,保证区域之间没有重合的部分。
对于 100% 的数据,保证 1≤𝑙≤104,1≤𝑚≤100,0≤𝑢≤𝑣≤𝑙。
题目来源
NOIP 2005 普及组第二题
代码:
#include<bits/stdc++.h>
using namespace std;
// 定义数组大小为100002,以覆盖题目中可能的最大范围
bool a[100002]; // 布尔数组,用于标记马路上每个位置是否有树(true表示有树)
int u[100002],v[100002]; // 定义两个数组分别存储各个区域的起始点和终止点
int main()
{
int l,m,cnt=1; // l为马路长度,m为区域数量,cnt初始化为1,用于计数剩余树木数量
cin>>l>>m; // 输入马路长度和区域数量
// 输入各个区域的起始点和终止点坐标
for(int i=1;i<=m;i++)
{
cin>>u[i]>>v[i];
}
// 初始化布尔数组a,表示最初马路上每个位置都有树
for(int i=1;i<=l;i++)
{
a[i]=true;
}
// 遍历所有区域,将对应区间内的树标记为不存在(false)
for(int i=1;i<=m;i++)
{
for(int j=u[i];j<=v[i];j++)
{
a[j]=false;
}
}
// 计算并输出剩余的树木数量
// 这里初始化cnt为1,因为从0开始到第一个位置默认有树,所以直接开始计数
for(int i=1;i<=l;i++)
{
if(a[i]==true)
{
cnt++; // 遇到标记为true的位置,说明该位置有树,树木计数加1
}
}
cout<<cnt; // 输出最终剩余的树木数量
return 0;
}
题目讲解:
首先,通过输入获取马路长度“l”和需要移除树木的区域数量"m"。接着,程序读取每一个区域的起始点和终止点坐标,并存储在数组"u[]"和"v[]"中。
初始化了一个布尔数组“a[]”,用于标记马路上每个位置是否原本有树。初始时,假定马路上除了起点外,每隔1米就有一棵树,因此数组“a[]”的元素都被设为true。
随后,遍历每个区域,将这些区域所覆盖的树(即数组“a[]”中对应的下标)标记为false,表示这些位置的树将被移除。
最后,通过遍历整个数组“a[]”,统计其中值为true的数量,即为最终马路上剩余的树木数量,并输出这个结果。
注意,代码中初始化cnt为1,这是因为计数是从马路的起点(位置0不算树,但默认从位置1开始有树)开始的,因此直接从1开始累加,确保了计数的准确性。
谢谢阅读!

361

被折叠的 条评论
为什么被折叠?



