刷题日记day4-路灯和区间问题



前言

简单写个日记记录我刷了什么题以及心得总结。
刚开始刷题,没什么经验和思路,编程也有点生疏。所以前期偏向于先想后直接看别人的思路求解然后再学习了。


一、问题复述

笔直的公路上有N的路灯,从0位置开始安装,路灯间隔固定100米。
各个路灯的照明半径不尽相同,求第一个路灯到最后一个路灯之间没有被照明的路径长度和。
输入:vector int r 为每盏路灯的照亮半径,int N为路灯数。
输出:int 未照明区域的总长度

二、解法及其思想

  • 需要考虑照亮半径存在过大、过小、有重叠区域等情况。
  • 题目给出照亮半径,将其转化为区间表示的话可以很方便地计算。
  • 使用容器vector<pair<int,int>>装载所有区间,在此基础上去除区间的重复部分。
  • sort()函数允许对pair<,>进行比较,可以直接用来对区间排序。
  • 排序之后即可遍历数组找出并去除重复区间。

三、代码实现及细节(仅算法相关部分)

//函数返回所求长度
int dis(vector<int> r,int N){
    //step1.计算出总长
    //设置合适的用于装载区间的容器:vector<pair<int,int>>
    int len=100*(N-1);
    vector<pair<int,int>> intervals;
    //step2.装载区间:遍历半径,根据半径得出区间
    //区间边界:最小为0,最大为len
    int begin,end;
    for(int i=0;i<N;i++){
        begin=max(0,i*100-r[i]);
        end=min(len,i*100+r[i]);
        intervals.push_back({begin,end});
    }
    //step3.排序
    //默认情况下,sort会根据pair的first 的值进行升序排序,当 first 相同时,会根据 second 的值进行升序排序
    sort(intervals.begin(),intervals.end());
    //step4.区间处理:处理重复区间
    //关系到两个区间的处理,因此需要临时值
    int prebegin=intervals[0].first;
    int preend=intervals[0].second;
    //prebegin、preend指两个区间中的前者
    for(int i=1;i<N;i++){
        begin=intervals[i].first;
        end=intervals[i].second;
        //如果后一个区间的左边界小于等于前一个区间的右边界,那么判定为重复,此时变动前一个区间的右边界
        if(begin<=preend){
            preend=max(preend,end);
        }else{//如果不重复,可直接计算未照明长度,并前移
            len-=(preend-prebegin);
            prebegin=begin;
            preend=end;
        }
    }
    /*
        上步中,最后一个区间与前一个区间重复了的话,照明区间没有减去;
        若不重复,最后一个区间也没有计算。
        无论如何,使用下面一行代码处理最后一个区间。
    */
    len-=(preend-prebegin);
    return len;
}

总结与感想

区间类问题头一次见。
别人的解题思路真是牛。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值