洛谷 【算法1-6】二分查找与二分答案

【算法1-6】二分查找与二分答案 - 题单 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

鄙人不才,刷洛谷,迎蓝桥,【算法1-6】二分查找与二分答案 已刷,现将 AC 代码献上,望有助于各位

P2249

【深基13.例1】查找 - 洛谷

题目

解答

思路

使用二分查找的方式解决

代码

#include<iostream>
using namespace std;
const int N = 1000005;
const int M = 100005;
int a[N], find_n[M];
void search(int aim, int l, int r) {if (l >= r && a[l] == aim) {cout << l + 1 << " ";return;}if (l >= r) {cout << "-1 ";return;}int mid = (l + r) / 2;if (aim <= a[mid])search(aim, l, mid);elsesearch(aim, mid + 1, r);
}
int main() {int n, m;cin >> n >> m;for (int i = 0; i < n; i++)cin >> a[i];for (int i = 0; i < m; i++)cin >> find_n[i];int q = 0;while (q < m) {search(find_n[q], 0, n - 1);q++;}return 0;
}

P1102 A-B 数对

A-B 数对 - 洛谷

题目

解答

思路

在一个数组中,寻找 A-B=C 的数值对 <A, B>,A-B=C 即 A-C=B ,求与 A 对应的 B 的个数

用 map 映射数组元素出现的次数 <value,times>

代码

#include<iostream>
#include<map>
using namespace std;
const int N = 200005;
long long int q[N], C;
map<int, int> a;
long long int n;
int main() {cin >> n >> C;for (int i = 0; i < n; i++) {cin >> q[i];a[q[i]]++;q[i] -= C;}long long int ans = 0;for (int i = 0; i < n; i++)ans += a[q[i]];cout << ans;return 0;
}

P1873 KEO / 砍树

[COCI 2011/2012 #5] EKO / 砍树 - 洛谷

题目

解答

思路

二分查找 H,0 ≤ H ≤ max_tree

  1. 排序 tree,寻找 max_tree
  2. 二分查找 H,判断条件为 实际伐木总长度 < m

代码

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1000005;
int tree[N];
long long int m;
int n;
int main() {cin >> n >> m;for (int i = 0; i < n; i++)cin >> tree[i];sort(tree, tree + n);int l = 0, r = tree[n - 1];while (l <= r) {int mid =( l + r )/ 2;long long sum = 0;for (int i = 0; i < n; i++)if (tree[i] > mid)sum += (tree[i] - mid);if (sum < m)r = mid - 1;elsel = mid + 1;}cout << r;return 0;
}

P1024 一元三次方程求解

[NOIP2001 提高组] 一元三次方程求解 - 洛谷

题目

解答

思路

浮点数二分

依据上述定理,使用二分算法求根

代码

#include<iostream>
#include<cstdio>
using namespace std;
double a, b, c, d;
double f(double x) {return a * x * x * x + b * x * x + c * x + d;
}
int main() {cin >> a >> b >> c >> d;int s = 0;double l, r, mid, f1, f2;for (int i = -100; i < 100; i++) {l = i;r = l + 1;f1 = f(l);f2 = f(r);if (!f1) {printf("%.2lf ", l);s++;}if (f1 * f2 < 0) {while (r - l > 0.0001) {mid = (l + r) / 2;if (f(mid) * f(r) <= 0)l = mid;elser = mid;}printf("%.2lf ", l);s++;}if (s == 3)break;}return 0;
}

P1678 烦恼的高考志愿

烦恼的高考志愿 - 洛谷

题目

解答

思路

先对学校的预计录取分数排序,然后二分查找每个学生最小的不满意度

代码

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 100005;
const int M = 100005;
int m, n;
long long int student[N], school[M];
int main() {cin >> m >> n;for (int i = 0; i < m; i++)cin >> school[i];for (int j = 0; j < n; j++)cin >> student[j];sort(school, school + m);long long int ans = 0;for (int i = 0; i < n; i++) {//逐个二分int l = 0, r = m - 1;while (l < r) {int mid = (l + r + 1) / 2;if (school[mid] <= student[i])l = mid;elser = mid - 1;}if (student[i] <= school[0])ans += (school[0] - student[i]);else {if (abs(school[l + 1] - student[i]) <= abs(school[l] - student[i]))ans += (abs(school[l + 1] - student[i]));elseans += (abs(school[l] - student[i]));}}cout << ans;return 0;
}

P2440 木材加工

木材加工 - 洛谷

题目

解答

思路

二分查找即可

代码

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100005;
int n;
long long int k;
long long int tree[N];
bool check(long long int a) {long long int ans = 0;for (int i = 0; i < n; i++)ans += tree[i] / a;if (ans >= k)return true;elsereturn false;
}
int main() {cin >> n >> k;for (int i = 0; i < n; i++)cin >> tree[i];sort(tree, tree + n);long long int l = 0, r = tree[n - 1];long long int mid;while (l + 1 < r) {//最终l = 114, r = 115,mid = 114, ans = 7//l < r, 继续循环 mid = 114,ans = 7, l = 114……无法退出循环mid = (l + r) / 2;if (check(mid))l = mid;elser = mid;}cout << l;return 0;
}

P2678 跳石头

[NOIP2015 提高组] 跳石头 - 洛谷

题目

解答

思路

二分查找最短距离的最大值

检测 mid 是否为最短距离?依次遍历相邻两块石头之间的距离,如果出现比 mid 小的距离,则将此块石头搬走,并记录搬走石头的块数;若搬走石头的块数 > m,则说明 mid 比实际的最小距离短,需要使用 mid 更新左边界;若搬走石头的块数 <= m,则说明 mid 比实际的最小距离长,需要使用 mid 更新右边界

代码

#include<iostream>
using namespace std;
long long int l;
const int N = 50005;
const int M = 50005;
int n, m;
long long int ans;
long long int s[N] = { 0 };
long long int max_m = 0, min_m = 0x3f3f3f3f;
bool check(long long int a) {//检测a是否为最短距离int count = 0;//count记录拿去石头的块数int front = 0;//front表示前一块石头for (int i = 1; i <= n + 1; i++) {if (s[i] - s[front] < a)//若两块石头之间的距离小于目前的最小距离,则将这块石头拿掉count++;elsefront = i;}if (count > m)return false;elsereturn true;
}
int main() {cin >> l >> n >> m;max_m = l;if (m == 0 && n == 0) {//只有起点和终点,中间没有石头的情况cout << l;return 0;}for (int i = 1; i <= n; i++) {cin >> s[i];long long int t = s[i] - s[i - 1];if (t < min_m)min_m = t;}s[n + 1] = l;if ((s[n + 1] - s[n]) < min_m)min_m = s[n - 1] - s[n];long long int mid;while (min_m <= max_m) {//不能去掉等号,否则少循环一次mid = (min_m + max_m) / 2;if (check(mid)) {ans = mid;min_m = mid + 1;//需要搬去的石头数<=m,说明现在的最短距离偏短,需要更大,更新最小边界}elsemax_m = mid - 1;//需要搬去的石头数>m,说明现在的最短距离>实际的最短距离,需要更小,更新最大边界}cout << ans;return 0;
}

P3853 路标设置

[TJOI2007] 路标设置 - 洛谷

题目

解答

思路

二分查找最长距离的最小值

检测 mid 是否为最长距离?依次遍历相邻两个路障之间的距离,如果出现比 mid 大的距离,则设置新的路障,并记录设置的路障的数量;若新设置的路障数 > k,则说明 mid 比实际的最长距离短,需要使用 mid 更新左边界;若新设置的路障数 <= k,则说明 mid 比实际的最长距离长,需要使用 mid 更新右边界

代码

代码

#include<iostream>
using namespace std;
long long int l;
const int N = 100005;
int k, n;
long long int s[N];
long long int ans;
bool check(long long int mid) {//检测mid是否为最大距离int y = k;int qian = 0;for (int i = 1; i < n; i++) {//遍历原路障,判断此路障与前一个路障直接是否需要安装新的路障if (y < 0)break;if ((s[i] - qian) <= mid)//此路障与前一个路障之间的距离<最大距离,继续遍历qian = s[i];else {//此路障与前一个路障之间的距离>最大距离,安装路障,新安装的路障与原前一个路障之间的距离为midqian = qian + mid;i--;//安装路障之后,不能直接判断原来的下一个路障,还得在此基础上,再次判断此处是否需要再次安装路障y--;}}if (y >= 0)return true;return false;
}
int main() {cin >> l >> n >> k;for (int i = 0; i < n; i++)cin >> s[i];long long int min_m = 0, max_m = l;while (min_m <= max_m) {long long int mid = min_m + (max_m - min_m) / 2;if (check(mid)) {ans = mid;max_m = mid - 1;//需要新设的路障<=k,说明现在的最长距离偏长,需要更短,更新最大边界}elsemin_m = mid + 1;//需要新设的路障>k,说明现在的最长距离偏短,需要更长,更新最小边界}cout << ans << endl;return 0;
}

P1182 数列分段 SectionⅡ

数列分段 Section II - 洛谷

题目

解答

思路

二分查找子序列和最大值的最小值

检测 mid 是否为子序列和的最大值?依次遍历数组元素,如果出现子序列和 >mid,则将当前元素作为新的子序列的第一个元素;若段数 >= m,则说明 mid 比实际的最大子序列和小,需要使用 mid 更新左边界;若段数 < m,则说明 mid 比实际的最大子序列和大,需要使用 mid 更新右边界

代码

#include<iostream>
using namespace std;
const int N = 100005;
int n, m;
long long int num[N], l = 0, r = 0x3f3f3f3f;
long long int ans;
bool check(long long int mid) {int cnt = 0, s = 0;for (int i = 0; i < n; i++) {if ((s + num[i]) <= mid)s += num[i];else {s = num[i];cnt++;}}return cnt >= m;
}
int main() {cin >> n >> m;for (int i = 0; i < n; i++) {cin >> num[i];if (l < num[i])l = num[i];r += num[i];}while (l <= r) {long long int mid = (l + r) / 2;if (check(mid))l = mid + 1;//实际划分的组数>=要求的组数,说明子序列和偏小,实际子序列和应该更大elser = mid - 1;//实际划分的组数<要求的组数,说明子序列和偏大,实际子序列和应该更小}cout << l;return 0;
}

P1163 银行贷款

银行贷款 - 洛谷

题目

解答

思路

二分查找月利率,查找的范围大一些,要包含所有的范围

遍历每一个月,每月先计算利息,再还款

还款结束后,若欠债为0,或二分查找范围小于 0.0001 时,表示已经找到月利率;

若存在欠债,说明月利率太大了,使得利息过多

若不存在欠债,且多还款了,说明月利率太小了,使得利息过少

代码

#include<iostream>
using namespace std;
double w_s, w;
double year;
double lx = 0;
double find(double l, double r) {double mid = (l + r) / 2;double qianzai = w_s;//表示目前的欠债for (int i = 0; i < year; i++) qianzai = qianzai * (1 + mid) - w;if (qianzai == 0 || r - l < 0.0001)return mid;if (qianzai < 0)return find(mid, r);elsereturn find(l, mid);
}
int main() {cin >> w_s >> w >> year;double h = find(0, 5);//二分,开大一点,保证所有数都可以通过printf("%.1lf", h * 100);return 0;
}

P3743 kotori 的设备

kotori的设备 - 洛谷

题目

解答

思路

二分查找设备使用时间

特判:用电量<=充电量,可以无限使用

如何查找设备最久使用时间?检测需要的充电量与实际充电量的关系,若需要的充电量<=实际充电量,说明设备使用时间<最久设备使用时间,更新二分的左边界;反之,说明设备使用时间>最久设备使用时间,更新二分的右边界

代码

#include<iostream>
using namespace std;
const int N = 100005;
double p;
int n;
double a[N], b[N];
double sum = 0;//需要的能量
bool check(double mid) {double max = p * mid;//max表示充电器最多提供的能力sum = 0;for (int i = 0; i < n; i++) {//遍历每一台设备if ((a[i] * mid) <= b[i])//设备已有的能量>需要的能量continue;sum = sum + ((a[i] * mid) - b[i]);//计算充电量}return sum <= max;
}
int main() {cin >> n >> p;for (int i = 0; i < n; i++) {cin >> a[i] >> b[i];sum += a[i];}//特判:无限使用if (sum <= p) {cout << "-1" << endl;return 0;}double l = 0, r = 1e10;while ((r - l) > 0.0001) {double mid = (l + r) / 2;if (check(mid))//需要的充电量<=实际充电量l = mid;elser = mid;}cout << l << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/487647.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python中if __name__ == ‘__main__‘:的原理、作用和实践

Python中if name ‘main‘&#xff1a;的原理、作用和实践 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 &#x1f448; 希望得到您的…

Unity之PUN2插件实现多人联机射击游戏

目录 &#x1f4d6;一、准备工作 &#x1f4fa;二、UI界面处理 &#x1f4f1;2.1 登录UI并连接PUN2服务器 &#x1f4f1;2.2 游戏大厅界面UI &#x1f4f1;2.3 创建房间UI &#x1f4f1;2.4 进入房间UI &#x1f4f1;2.5 玩家准备状态 &#x1f4f1;2.6 加载战斗场景…

电子元件分销商

Top 10 Active Electronic Parts Distributors List – 2022 / 2023 一家从众多制造商那里收购所有电子元件并销售给客户的公司被称为电子元件分销商。 A company that acquires all electronic components from numerous manufacturers and sells them to customers from a si…

第十一天-Excel的操作

目录 1.xlrd-Excel的读模块 安装 使用 获取工作簿 读取工作簿的内容 xlsxwriter-Excel的写模块 安装 使用 生成图表 add_series参数 图表的样式 demo&#xff1a;生成图表 Excel的操作在python中有多个模块&#xff0c;为了能够快速使用&#xff0c;选择了相对简单…

【Java程序设计】【C00276】基于Springboot的就业信息管理系统(有论文)

基于Springboot的就业信息管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的就业信息管理系统 本系统分为前台功能模块、管理员功能模块、学生功能模块、企业功能模块以及导师功能模块。 前台功能模块&…

Threejs 实现3D影像地图,Json地图,地图下钻

1.使用threejs实现3D影像地图效果&#xff0c;整体效果看起来还可以&#xff0c;底层抽象了基类&#xff0c;实现了通用&#xff0c;对任意省份&#xff0c;城市都可以只替换数据&#xff0c;即可轻松实现效果。 效果如下&#xff1a; 链接https://www.bilibili.com/video/BV1…

HMI界面:是工业自动化的“窗口”,大有用武之地。

Hello&#xff0c;我是大千UI工场&#xff0c;本期分享HMI人机交互界面在工业自动化领域的应用&#xff0c;关注大千&#xff0c;学习N多UI干货&#xff0c;有设计需求&#xff0c;我们也可以接单。 HMI&#xff08;Human Machine Interface&#xff0c;人机界面&#xff09;在…

Redis篇之Redis持久化的实现

持久化即把数据保存到可以永久保存的存储设备当中&#xff08;磁盘&#xff09;。因为Redis是基于内存存储数据的&#xff0c;一旦redis实例当即数据将会全部丢失&#xff0c;所以需要有某些机制将内存中的数据持久化到磁盘以备发生宕机时能够进行恢复&#xff0c;这一过程就称…

Android LruCache源码分析

文章目录 Android LruCache源码分析概述LruCache和LinkedHashMap关系源码分析属性写入数据读取数据删除缓存 Android LruCache源码分析 概述 LruCache&#xff08;Least Recently Used Cache&#xff0c;最近最少使用缓存&#xff09;是 Android 中的一种缓存机制。 根据数据…

Nginx跳转模块之rewrite

一.location与rewrite模块的区别 rewrite&#xff1a;对访问的域名或者域名内的URL路径地址重写 location&#xff1a;对访问的路径做访问控制或者代理转发 二.rewrite模块基本内容 1.功能 通过正则表达式的匹配来改变URI&#xff0c;可以同时存在一个或多个指令&#xff0c…

SpringBoot3+Vue3 基础知识(持续更新中~)

bean 把方法的返回结果注入到ioc中 1: 2: 3: 组合注解封装 实战篇&#xff1a; 解析token&#xff1a; 统一携带token&#xff1a; 驼峰命名与下划线命名转换&#xff1a;

WebAPI [Swagger] 发布ISS不能生成xml文件问题记录

因为Swagger文件的注释是读取项目xml的。 除了Debug要输出xml&#xff0c;正式发布release时也要输出xml