洛谷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站上有因此这里只是简单解释了下,大家如果觉得有问题的话也可以私信问我我尽量解释清楚

相关推荐
历程里程碑2 小时前
40 UDP - 2 C++实现英汉词典查询服务
linux·开发语言·数据结构·c++·ide·c#·vim
木二_2 小时前
056.Kubernetes cert-manager Root CA自签实战
算法·容器·kubernetes
老赵聊算法、大模型备案2 小时前
网信办公示 2026 年 1-2 月生成式 AI 备案登记情况:新增 94 款,累计突破 1200 款
人工智能·算法·安全·aigc
code_whiter2 小时前
C++3(类与对象中篇)
c++
学嵌入式的小杨同学2 小时前
STM32 进阶封神之路(十三):空气质量传感器实战 ——KQM6600 模块从协议到代码(串口通信 + 数据解析)
c++·stm32·单片机·嵌入式硬件·架构·硬件架构·嵌入式实时数据库
x_xbx2 小时前
LeetCode:21. 合并两个有序链表
算法·leetcode·链表
2501_945423542 小时前
C++与Rust交互编程
开发语言·c++·算法
我能坚持多久2 小时前
【初阶数据结构10】——链式二叉树的功能实现
数据结构·算法
tankeven2 小时前
HJ131 数独数组
c++·算法