学而思编程2025年CodeStars年度综合评估真题解析 | 基础算法组 T1 除虫计划

​欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总贴:学而思编程2025年CodeStars年度综合评估真题解析 | 汇总


【题目来源】

小猴编程:学而思编程CodeStars年度综合评估

【题目描述】

皮皮家有 N N N 块的麦田排列成一行,每一块麦田的编号为 1 , 2 , 3 , … , N 1,2,3,…,N 1,2,3,,N。盛夏就要到了,为了能让麦田里的麦子茁壮生长,皮皮必须派遣无人机给麦田喷洒农药,去消灭不利于麦子生长的害虫。

皮皮会给无人机输入 M M M 条指令,每一条指令包含两个正整数 l i l_i li r i r_i ri ,无人机会对第 l i ∼ r i l_i∼r_i liri 号麦田喷洒农药 。可是指令太多了,皮皮也不清楚在他输入完 M M M 条指令之后能否完成除虫的任务。

所以皮皮找到了你,他希望你告诉他在无人机执行完所有指令之后,麦田中还有几片区域没有被喷洒到农药, 还有这些没有被喷洒到农药的区域中最大的区域是多大?(如果有若干块连续的麦田都没有被喷洒农药,那么它们看作一片区域)

【输入】

第一行两个正整数 N N N M M M ,表示麦田个数以及指令个数。

接下来 M M M 行,每行两个正整数 l i l_i li r i r_i ri ,表示需要喷洒农药的区域,保证 l i ≤ r i l_i≤r_i liri

【输出】

输出两行,每行一个整数

第一行表示没有被喷洒到农药的区域个数。

第二行表示这些区域中最大的麦田个数。

【输入样例】

10 3
1 3
5 6
9 10

【输出样例】

2
2

【代码详解】

#include 
using namespace std;

const int N = 100005;  // 定义最大区间长度

int n, m;       // n: 区间长度,m: 操作次数
int a[N];       // 差分数组,用于记录区间覆盖情况

int main() 
{
    // 输入区间长度n和操作次数m
    cin >> n >> m;

    // 处理每个区间操作[l,r]
    for (int i = 1; i <= m; i++) 
	{
        int l, r;
        cin >> l >> r;
        // 差分数组标记:区间开始处+1,结束处+1的位置-1
        a[l]++;
        a[r + 1]--;
    }

    // 计算前缀和,得到每个位置被覆盖的次数
    for (int i = 1; i <= n; i++) 
        a[i] += a[i - 1];

    // 调试输出(已注释)
    /*
    for (int i = 1; i <= n; i++)
        cout << a[i] << " ";
    cout << endl;
    */

    int maxn = -1;    // 记录最长连续未被覆盖区间的长度
    int cnt = 0;      // 当前连续未被覆盖区间的长度计数器
    int flag = 0;     // 标记是否开始统计新区间
    int res = 0;      // 记录未被覆盖的连续区间总数

    // 遍历整个区间,统计未被覆盖的区域
    for (int i = 1; i <= n; i++) 
	{
        if (a[i] == 0)   // 当前位置未被覆盖
		{
            cnt++;         // 增加当前连续未被覆盖区间的长度
            if (flag == 0) // 如果是新区间的开始
                res++;     // 增加未被覆盖区间总数
            flag = 1;      // 标记已开始统计区间
        } 
		else            // 当前位置被覆盖
		{
            maxn = max(maxn, cnt);  // 更新最长连续未被覆盖区间长度
            cnt = 0;       // 重置计数器
            flag = 0;      // 标记区间结束
        }
    }
    maxn = max(maxn, cnt); // 检查最后一段区间

    // 输出结果
    cout << res << endl;    // 输出未被覆盖的连续区间总数
    cout << maxn << endl;   // 输出最长连续未被覆盖区间的长度

    return 0;
}

【运行结果】

10 3
1 3
5 6
9 10
2
2

你可能感兴趣的:(算法)