区间问题——905. 区间选点

目录

区间问题

定义

运用情况

注意事项

解题思路

AcWing 905. 区间选点

题目描述

运行代码

代码思路

改进思路

其它代码

代码思路

区间问题

定义

区间通常是指一个连续的范围,可以用数轴上的一段来表示。

运用情况

  • 在数学中广泛用于表示变量的取值范围,如函数的定义域、值域等。
  • 在统计学中用于描述数据的分布区间。
  • 在实际生活中,如时间区间、温度区间等。

注意事项

  • 明确区间的端点是否包含在内(开区间或闭区间)。
  • 对于多个区间的组合,要仔细分析它们之间的关系。
  • 在计算和推理时,要确保区间的定义和条件始终一致。

解题思路

  • 首先确定区间的类型(开区间、闭区间等)。
  • 根据题目条件,列出相关方程或不等式来确定区间的范围。
  • 对于复杂的区间问题,可以通过图形来辅助理解和分析。
  • 检查答案是否满足区间的定义和题目要求。

AcWing 905. 区间选点

题目描述

905. 区间选点 - AcWing题库

运行代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
    int n;
    cin >> n;
    vector<pair<int, int>> intervals(n);
    for (int i = 0; i < n; i++) {
        cin >> intervals[i].first >> intervals[i].second;
    }
    sort(intervals.begin(), intervals.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
        return a.second < b.second;
    });
    int ans = 0, lastPoint = -1000000001;
    for (const auto& interval : intervals) {
        if (interval.first > lastPoint) {
            ans++;
            lastPoint = interval.second;
        }
    }
    cout << ans << endl;
return 0;
}

代码思路

  • 首先,读取区间的数量 n
  • 创建一个 vector<pair<int, int>> 来存储所有的区间。
  • 通过循环读取每个区间的左右端点并存储到 intervals 中。
  • 然后对区间按照右端点进行排序,这样可以保证先处理右边界较小的区间。
  • 初始化结果 ans 为 0,以及一个表示上一个选择的点的位置 lastPoint 为一个极小值。
  • 遍历排序后的区间:如果当前区间的左端点大于上一个选择的点的位置,说明需要在这个区间内选择一个新的点,将结果加 1,并更新 lastPoint 为当前区间的右端点。这样就可以保证每个区间都至少有一个点被选中,且是尽可能少的点。最后输出结果。
  • 这种贪心策略的核心在于优先处理右边界较小的区间,通过不断更新选择点的位置来满足所有区间的覆盖要求。

改进思路

  1. 添加输入有效性检查:可以在读取 n 以及区间端点值时,添加一些检查来确保输入数据的合法性。
  2. 考虑使用更高效的数据结构:如果对性能要求较高,可以研究是否有更适合的数据结构来存储和处理区间信息。
  3. 添加必要的注释:进一步增加代码的注释,以提高代码的可理解性。
  4. 异常处理:考虑添加一些针对可能出现的异常情况(如输入错误、排序失败等)的处理机制。
  5. 代码重构:对一些逻辑部分进行重构,使其结构更加清晰,逻辑更加简洁。
  6. 性能优化:分析代码中可能存在的性能瓶颈,进行针对性优化,比如尝试不同的排序算法等。

其它代码

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct R
{
    int l, r;
    bool operator < (const R &W)const
    {
        return r < W.r;
    }
}r[N];
int main()
{
    int n; cin >> n;
    for(int i = 0; i < n ; i++)
    {
        int a, b; cin >> a >> b;
        r[i] = {a, b};
    }
    sort(r, r + n);
    int ans = 0, right = -2e9;
    for(int i = 0; i < n; i++)
    {
        if(r[i].l > right)
        {
            ans ++;
            right = r[i].r;
        }
    }
    cout << ans << endl;
    return 0;
}

代码思路

  • 定义了一个结构体 R 来表示区间,包含左端点 l 和右端点 r,并定义了结构体之间的比较运算符,按照右端点从小到大排序。
  • 在 main 函数中,首先输入区间的数量 n,然后依次输入每个区间的左右端点,并将其存储在 r 数组中。
  • 通过 sort 函数对区间数组按照右端点排序。
  • 然后通过遍历数组,使用一个变量 right 来记录当前已经覆盖到的最右端位置。如果当前区间的左端点大于 right,说明这是一个新的不重叠区间,就将结果加 1,并更新 right 为当前区间的右端点。最后输出不重叠区间的数量。

总的来说,这段代码的目的是通过对区间进行排序和遍历,计算出不重叠区间的最大数量。例如,假设有一系列区间 [1, 3][2, 4][4, 6],经过处理后可以得出有 2 个不重叠区间([1, 3] 和 [4, 6])。

  • 38
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱姌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值