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

相关推荐
卷福同学4 小时前
不用服务器,不用配环境,我10分钟上线了一个AI Agent
人工智能·后端·算法
问君能有几多愁~6 小时前
C++ 数据结构复习笔记
数据结构·c++·笔记
至乐活着6 小时前
深入解析跳表SkipList:原理、实现与性能优化实战
数据结构·算法·跳表·skiplist·java实现
tntxia6 小时前
C++ 基础教程:从入门到精通
c++
Drone_xjw6 小时前
从 GDB 到 CDB:C/C++ 程序调试的两把“手术刀”
c语言·开发语言·c++
Jerry7 小时前
LeetCode 383. 赎金信
算法
ai产品老杨7 小时前
H264 H265视频分析常见问题和排查清单
人工智能·算法·音视频
Jerry8 小时前
LeetCode 454. 四数相加 II
算法
可编程芯片开发8 小时前
基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真
算法
Jerry9 小时前
LeetCode 202. 快乐数
算法