hw2021笔试第三场第一题

博客讲述了在hw2021笔试中遇到的一道题目,内容涉及寻找覆盖所有工位的最小消毒器械工作半径。通过分析,作者采用二分法来解决,首先确定半径的上界,然后不断减小半径直至无法覆盖所有工位,找到左边界。关键在于判断半径是否满足条件,通过计算消毒器械的工作范围并合并重叠区间,确保所有工位被覆盖。最终实现代码中包含二分查找和区间判断的逻辑。
摘要由CSDN通过智能技术生成

hw2021笔试第三场第一题

  一开始死活通不过,一直为0,后来加了一句代码,过了80%,要哭了……

题目描述

  有一条水平线,水平线上有一些工位和消毒器械,位置均固定。消毒器械的工作范围是一个圆形,且所有的消毒器械工作半径均相同。要求覆盖所有的工位,试求,最小的工作半径为多少?

  输入:第一行输入一个数组,代表工位位置;第二行输入一个数组,代表消毒器械的位置。

  输出:最小工作半径大小

  示例:

  输入:

  1 3 5

  2

  输出:

  3

  即,工作半径为3,消毒器械位置位于2,这样就可以覆盖所有工位1、3、5了。

思路

  首先,工位和消毒器械都在同一条水平线上,还知道两者的位置,画个数轴就明确了。

示意图

  用暴力的话,两层for循环,依次判断每个工位是否可以在某个消毒器械的范围内即可,但是很容易就超时了。换个思路,如果设置半径r为最远处的工位(5),是一定满足要求的。既然5可以,4是否可以,……,直到r为2时不满足条件,因此得到最小的工作半径为3。所以就变成了寻找半径可选值的左边界值,也就是最小的最大值,这样就可以用二分寻找了(可以看这个二分法代码分析-寻找左边界),即如果mid值符合要求,就继续向左找。二分部分代码如下:

void binarySearch(const vector<int>& work, const vector<int>& ster)
{
   
	int small = 1, mid, big = maxWorkStation;
	
	while (small <= big) {
   
		mid = small + (big - small) / 2;
		if (judge(work, ster, mid)) {
   
			big = mid - 1;
		} else {
   
			small = mid + 1;
		}
	}
	
	cout << small << endl; // big + 1也可
}

  现在的关键就是如何判断半径r是满足要求的。我是在读入消毒器械位置后,计算了每个消毒器械工作范围的区间,即只记录区间两端的数值。如果两个消毒器械有重叠的工作范围,则将其合并为一个大区间,例如(1,3),(2,4)可合并为(1,4)。最后依次判断每个工位是否在这一系列区间内。(ps:如果要合并重叠区间的话,记得给第二行的输入数据排个序,就是因为这个一直0%)。判断部分代码如下:

bool judge(const vector<int>& work, const vector<int>& ster, int r)
{
   
    vector<vector<int>> arr; // 存储区间端点值

    vector<int> tmp;
    tmp.push_back(ster[0] - r > 0 ? (ster[0] 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值