洛谷p1046:用一个题练习排序+二分查找

以上是题目要求,虽然数据量很少我们可以直接用一个count变量记录然后循环10次挨着比大小。但是不难发现这个题完全可以先对数组排序随后找到第一个大于能触及的最大高度的值的所在下标(下标从0开始则下标为i代表前面有i个数)。因此我们可以使用排序+二分的思路进行操作。

排序的代码我之前写过插排冒泡和选择。这个题排序不是重点我们当然也可以直接用sort,但这里我为了锻炼下自己对排序算法的熟练度因此写的冒泡排序。

剩下就是关键的二分查找代码。我代码的模板是看的灵茶山艾府大佬的,大家感兴趣最好看下原视频。这里我简单复述下实现思路:对于一个有序数组,若当前一个元素是小于目标值的,则其左边也肯定小于,而我们的目标是寻找第一个>=目标值的函数因此下次可以把左边界更新为mid+1(取mid就可以实现每次都排除一半的数)。那如果mid所在的数>=目标值我们就让r=mid-1;(r右边的数肯定都>=,但我们要找的是第一个>=,因此继续让r指针左移。由于我们始终保证r的右边>=目标值而l的左边小于目标值。那么当退出循环时刚好是l在r的右边,即此时l就是我们要找的第一个>=目标值的下标(r的右边是>=的,但我们要的是第一个,因此当r在l的左边时就能确定是第一个)。这个题由于要找的是第一个大于目标值的数,实际等效于找到第一个>=目标值+1的数。因此代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main(){
	int a[10];
	int h;
	
	for(int i=0;i<10;i++){
		cin>>a[i];
	}
	cin>>h;
	
	int end = 9;
	bool flag = true;
	while(flag){
		flag = false;
		for(int i=0;i<end;i++){
			
			if(a[i]>a[i+1]){
				swap(a[i],a[i+1]);
				flag = true;
			}
		}
		end--;
	}
	int tar = h+30;
	//寻找第一个大于tar的数,其前面的数则都可以取到
	int l=0,r=9;
	while(l<=r){
		int mid = l+(r-l)/2;
		if(a[mid]<tar+1){
			l=mid+1;
		}else{
			r=mid-1;
		}
	} 
	cout<<l;
}

这个题是很简单的,只是刚好可以用来训练下排序和二分查找的写法,因此我觉得大家如果对这两块的算法实现不太熟悉的话可以用这个题来练下。因为算法模板b站上有因此这里只是简单解释了下,大家如果觉得有问题的话也可以私信问我我尽量解释清楚

相关推荐
LuminousCPP21 分钟前
从零开始学 C++(三):类和对象入门|从 struct 到 class,理解封装、对象与 this 指针
c++·笔记·学习·类和对象
郝学胜-神的一滴27 分钟前
游戏引擎原理与实践 01:聊聊游戏引擎的前世今生
开发语言·c++·游戏引擎·产品运营·软件工程·产品经理·untiy
Allen_LVyingbo1 小时前
信息化部门在AI时代的编程转移路径分析(上)
人工智能·python·算法·健康医疗·数据库开发·时序数据库·数据库架构
七牛云行业应用1 小时前
Jev 报 401 / api_key_required 怎么解决:TypeSafe AI 官方错误码表与排查步骤
算法·github
晴天的雨.9921 小时前
【C++算法】三数之和
开发语言·c++·算法
pippocao1 小时前
王者荣耀日志组件BqLog 为何如此快之3——压缩日志执行路径优化
c++
AC赳赳老秦1 小时前
公开 CSV 数据集批量处理实战:用 OpenClaw 高效完成下载、清洗与标准化分析样本生成
java·开发语言·汇编·c++·python·deepseek·openclaw
凉茶钱2 小时前
【吃透C++】static、友元、内部类、匿名对象与拷贝编译器优化全解析
c++·青少年编程·visual studio
无名猿2 小时前
左值引用、右值引用与万能引用:引用折叠全解
c++·现代c++·模板元编程·语法基础
多多爱学习2 小时前
括号有几层?得看还有多少个左括号没闭合
c语言·c++·算法·面试