2024蓝桥杯省赛保奖突击班-Day1-二分查找_笔记_练习题解

2024-03-26 16:12

本文主要是介绍2024蓝桥杯省赛保奖突击班-Day1-二分查找_笔记_练习题解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

3月22日-课堂笔记

  • 非降序序列二分查找等于 x x x 的数下标
int find(int x, int l, int r) {while(l < r) {int mid = (l + r) / 2;if(x <= a[mid]) r = mid;else l = mid + 1;}return l;
}
  • 非降序可重序列下标最小 ≥ x \geq x x 的元素
int find(int x, int l, int r) {while(l < r) {int mid = (l + r) / 2;if(a[mid] >= x) r = mid;else l = mid + 1;}return l;
}
  • C++ STL 的使用
vector<int> a(n);
int id = lower_bound(a.begin(), a.end(), x) - a.begin();
int id = upper_bound(a.begin(), a.end(), x) - a.begin();
int a[N];
int id = lower_bound(a + 1, a + n + 1, x) - a;
int id = upper_bound(a + 1, a + n + 1, x) - a;
  • a中元素 x x x 出现的次数 O ( log ⁡ n ) \mathcal{O}(\log n) O(logn)
int count = upper_bound(a.begin(),a.end(),x)lower_bound(a.begin(),a.end(),x);

练习题解

P1102 A-B 数对

题目链接:P1102
参考思路

对于给定的 A − B = C A-B=C AB=C,其中 C C C已知,那么我们可以枚举 A A A二分查找 B B B的范围,其中

C++参考代码
//用系统库函数
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N];
signed main() {ios::sync_with_stdio(false);cin.tie(NULL);int n, C;cin >> n >> C;for(int i = 1; i <= n; ++ i) cin >> a[i];sort(a + 1, a + n + 1);long long ans = 0;for(int i = 1; i <= n; ++ i) {int L = lower_bound(a + 1, a + n + 1, a[i] - C) - a;int R = upper_bound(a + 1, a + n + 1, a[i] - C) - a - 1;ans += R - L + 1;}cout << ans << endl;return 0;
}
//方便大家理解手动实现了一下函数
#include <bits/stdc++.h>using namespace std;int lowerBound(const vector<int>& a, int key) {int low = 0, high = a.size();while (low < high) {int mid = (low + high) / 2;if (a[mid] < key) {low = mid + 1;} else {high = mid;}}return low;
}int upperBound(const vector<int>& a, int key) {int low = 0, high = a.size();while (low < high) {int mid = (low + high) / 2;if (a[mid] <= key) {low = mid + 1;} else {high = mid;}}return low;
}int main() {int n, C;cin >> n >> C;vector<int> a(n);for (int i = 0; i < n; ++i) {cin >> a[i];}sort(a.begin(), a.end());long long ans = 0;for (int i = 0; i < n; ++i) {int L = lowerBound(a, a[i] - C);int R = upperBound(a, a[i] - C);ans += R - L;}cout << ans << endl;return 0;
}
Java参考代码
import java.util.*;
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n, C;n = scanner.nextInt();C = scanner.nextInt();int[] a = new int[n];for (int i = 0; i < n; ++i) {a[i] = scanner.nextInt();}Arrays.sort(a);long ans = 0;for (int i = 0; i < n; ++i) {int L = lowerBound(a, a[i] - C);int R = upperBound(a, a[i] - C);ans += R - L;}System.out.println(ans);scanner.close();}static int lowerBound(int[] a, int key) {int low = 0;int high = a.length;while (low < high) {int mid = (low + high) / 2;if (a[mid] < key) {low = mid + 1;} else {high = mid;}}return low;}static int upperBound(int[] a, int key) {int low = 0;int high = a.length;while (low < high) {int mid = (low + high) / 2;if (a[mid] <= key) {low = mid + 1;} else {high = mid;}}return low;}
}
Python参考代码
def lower_bound(a, key):low, high = 0, len(a)while low < high:mid = (low + high) // 2if a[mid] < key:low = mid + 1else:high = midreturn lowdef upper_bound(a, key):low, high = 0, len(a)while low < high:mid = (low + high) // 2if a[mid] <= key:low = mid + 1else:high = midreturn lowdef main():n, C = map(int, input().split())a = list(map(int, input().split()))a.sort()ans = 0for i in range(n):L = lower_bound(a, a[i] - C)R = upper_bound(a, a[i] - C)ans += R - Lprint(ans)if __name__ == "__main__":main()

P1678 烦恼的高考志愿

题目链接:P1678
参考思路
  • 题目意思其实就是求某一个学生和某一个分数线最小的差的绝对值,求和。
  • 那么我们先对学校分数线 a a a数组排序,然后对于每一个学生 b i b_i bi去学校分数也就是 a a a数组中二分查找学生分数 b i b_i bi左右两边最近的数即:最后一个小于等于 b i b_i bi的数和第一个大于等于 b i b_i bi的数。
  • 特别注意特殊处理当所有的分数都高于或者低于学生分数的情况。
C++参考代码
#include <bits/stdc++.h>using namespace std;
const int N = 1e5 + 10;
int a[N], b[N];
int findr(int t, int l, int r) {while (l < r) {int mid = (l + r) / 2;if (t <= a[mid]) {r = mid;} else {l = mid + 1;}}return l;
}int findl(int t,int l, int r) {while (l < r) {int mid = (l + r + 1) / 2;if (t >= a[mid]) {l = mid;} else {r = mid - 1;}}return l;
}
int main() {int m, n;cin >> m >> n;for (int i = 0; i < m; i++)cin >> a[i];for (int i = 0; i < n; i++)cin >> b[i];sort(a, a + m);long long res = 0;for (int i = 0; i < n; i++) {if (b[i] <= a[0])res += abs(b[i] - a[0]);else if (b[i] >= a[m - 1])res += abs(b[i] - a[m - 1]);else {int l = a[findr(b[i], 0, m)];int r = a[findl(b[i], 0, m)];int ls = abs(l - b[i]);int rs = abs(r - b[i]);if (ls < rs) {res += ls;} else {res += rs;}}}cout << res << endl;return 0;
}
Java参考代码
import java.util.*;public class Main {static int[] a = new int[100010];static int[] b = new int[100010];static int findr(int t, int l, int r) {while (l < r) {int mid = (l + r) / 2;if (t <= a[mid]) {r = mid;} else {l = mid + 1;}}return l;}static int findl(int t, int l, int r) {while (l < r) {int mid = (l + r + 1) / 2;if (t >= a[mid]) {l = mid;} else {r = mid - 1;}}return l;}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int m = scanner.nextInt();int n = scanner.nextInt();for (int i = 0; i < m; i++)a[i] = scanner.nextInt();for (int i = 0; i < n; i++)b[i] = scanner.nextInt();Arrays.sort(a, 0, m);long res = 0;for (int i = 0; i < n; i++) {if (b[i] <= a[0])res += Math.abs(b[i] - a[0]);else if (b[i] >= a[m - 1])res += Math.abs(b[i] - a[m - 1]);else {int l = a[findr(b[i], 0, m)];int r = a[findl(b[i], 0, m - 1)];int ls = Math.abs(l - b[i]);int rs = Math.abs(r - b[i]);if (ls < rs) {res += ls;} else {res += rs;}}}System.out.println(res);}
}
Python参考代码
def findr(t, l, r):while l < r:mid = (l + r) // 2if t <= a[mid]:r = midelse:l = mid + 1return ldef findl(t, l, r):while l < r:mid = (l + r + 1) // 2if t >= a[mid]:l = midelse:r = mid - 1return lm, n = map(int, input().split())
a = list(map(int,input().split()))
b = list(map(int,input().split()))a.sort()res = 0
for i in range(n):if b[i] <= a[0]:res += abs(b[i] - a[0])elif b[i] >= a[m - 1]:res += abs(b[i] - a[m - 1])else:l = a[findr(b[i], 0, m)]r = a[findl(b[i], 0, m - 1)]ls = abs(l - b[i])rs = abs(r - b[i])if ls < rs:res += lselse:res += rsprint(res)

P1918 保龄球

题目链接:P1918
思路:其实就是找这个数存在的位置,不存在输出0,可以用map记录位置也可以二分查找,大家可以参考:官方题解

这篇关于2024蓝桥杯省赛保奖突击班-Day1-二分查找_笔记_练习题解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/849072

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

poj 3104 二分答案

题意: n件湿度为num的衣服,每秒钟自己可以蒸发掉1个湿度。 然而如果使用了暖炉,每秒可以烧掉k个湿度,但不计算蒸发了。 现在问这么多的衣服,怎么烧事件最短。 解析: 二分答案咯。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <c