【CSP-J】[2005J2]校门外的树 题解

制作不易,请多多支持!记得点个赞!👍


题目描述
某校大门外长度为 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开始累加,确保了计数的准确性。


谢谢阅读!

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值