当前位置: 首页 > news >正文

二分查找与二分答案入门c++

目录

P2249 【深基13.例1】查找 - 洛谷 (luogu.com.cn)

P1102 A-B 数对 - 洛谷 (luogu.com.cn)

P1678 烦恼的高考志愿 - 洛谷 (luogu.com.cn)

P2440 木材加工 - 洛谷 (luogu.com.cn)


P2249 【深基13.例1】查找 - 洛谷 (luogu.com.cn)

比原来的二分多一步,即寻找第一次出现的位置,所以while循环中相等的情况需要额外判断是不是第一次。需要注意应该写while (left <= right)

#include<iostream>
#include<vector>
using namespace std;
int main() {
	int n, m;
	int t;
	cin >> n >> m;
	vector<int> a(n + 1);
	for (int i = 1; i <= n; i++) cin >> a[i];
	for (int i = 0; i < m; i++) {
		cin >> t;
		int res = -1;
		int left = 1;
		int right = n;
		while (left <= right) {
			int mid = left + ((right - left) >> 1);
			if (a[mid] > t) {
				right = mid - 1;
			}
			else if (a[mid] < t) {
				left = mid + 1;
			}
			else if (a[mid] == t) {
				res = mid;
				right = mid-1 ;
			}
		}
		cout << res << " ";
	}
	return 0;
}

P1102 A-B 数对 - 洛谷 (luogu.com.cn)

a-b=c转化为a=b+c,找到所有的a使b+c=a

找a的时候用二分,可以拿92分(样例3TLE力)

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int n, c;
	scanf("%d %d", &n, &c);
	vector<int> a(n);
	for (int i = 0; i < n; i++)cin >> a[i];
	sort(a.begin(), a.end());
	int res = 0;
	//a-b=c转化为a=b+c
	for (int i = 0; i < n; i++) {
		int b = a[i];
		//找到所有的a使b+c=a
		int left = 0;
		int right = n - 1;
		int t = -1;
		while (left <= right) {
			int mid = left + ((right - left) >> 1);
			if (a[mid] > (b + c)) right = mid - 1;
			else if (a[mid] < (b + c)) left = mid + 1;
			else {
				t = mid;
				right = mid - 1;
			}
		}
		if (t != -1) {
			while (t < n && (a[t] == b + c)) {
				res++;
				t++;
			}
		}
	}
	printf("%d\n", res);
	return 0;
}

介绍两个非常好用的函数,方法和上面一样,详见注释

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
	int n, c;
	scanf("%d %d", &n, &c);
	vector<int> a(n);
	for (int i = 0; i < n; i++)cin >> a[i];
	sort(a.begin(), a.end());
	int res = 0;
	for (int i = 0; i < n; i++) {
		res += upper_bound(a.begin(), a.end(), a[i] + c) - lower_bound(a.begin(), a.end(), a[i] + c);
		//upper_bound:找到最后一个与a[i] + c相等的数
		//lower_bound:找到第一个与a[i] + c相等的数
	}
	printf("%d\n", res);
	return 0;
}

可惜还是过不去 

原来是要开long long。。。。。。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#define int long long
signed main() {
	int n, c;
	scanf("%lld %lld", &n, &c);
	vector<int> a(n);
	for (int i = 0; i < n; i++)cin >> a[i];
	sort(a.begin(), a.end());
	int res = 0;
	for (int i = 0; i < n; i++) {
		res += upper_bound(a.begin(), a.end(), a[i] + c) - lower_bound(a.begin(), a.end(), a[i] + c);
		//upper_bound:找到最后一个与a[i] + c相等的数
		//lower_bound:找到第一个与a[i] + c相等的数
	}
	printf("%lld\n", res);
	return 0;
}

欧耶,过了过了过了!

P1678 烦恼的高考志愿 - 洛谷 (luogu.com.cn)

给学校排序,根据学生的分数找学校(二分),直到找到小于等于学生分数的学校

#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define int long long
signed main() {
	int m, n;
	cin >> m >> n;
	int res = 0;
	vector<int> sch(m);
	vector<int> stu(n);
	for (int i = 0; i < m; i++)cin >> sch[i];
	for (int i = 0; i < n; i++)cin >> stu[i];
	sort(sch.begin(), sch.end());
	for (int i = 0; i < n; i++) {
		int left = 0;
		int right = m - 1;
		while (left <= right) {
			int mid = left + ((right - left) >> 1);
			if (sch[mid] > stu[i])right = mid - 1;
			else if (sch[mid] < stu[i]) {
				if (mid + 1 == m) {
					left = mid;
					break;
				}
				else {
					if (sch[mid + 1] > stu[i]) {
						left = mid;
						break;
					}
					else if (sch[mid + 1] == stu[i]) {
						left = mid + 1;
						break;
					}
					else left = mid + 1;
				}
			}
			else {
				left = mid;
				break;
			}
		}
		if (left != (m - 1)) {
			int x = abs(sch[left] - stu[i]);
			int y = abs(sch[left + 1] - stu[i]);
			if (x > y)res += y;
			else res += x;
		}
		else res += abs(sch[left] - stu[i]);
	}
	cout << res << endl;
	return 0;
}

二分的时候看起来很麻烦,虽然还是AC了

P2440 木材加工 - 洛谷 (luogu.com.cn)

对切出来的最大值进行二分

#include<iostream>
#include<vector>
using namespace std;
#define int long long
signed main() {
	int n, k;
	cin >> n >> k;
	vector<int> a(n);
	int sum = 0;
	int f = 0;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		if (a[i] == 1)f = 1;
		sum += a[i];
	}
	if (sum / k == 0) {
		cout << 0 << endl;
		return 0;
	}
	else {
		if (f == 1) {
			cout << 1 << endl;
			return 0;
		}
	}
	int left = 0;
	int right = sum / k;
	int res = 0;
	while (left <= right) {
		int mid = left + ((right - left) >> 1);
		int count = 0;
		for (int i = 0; i < n; i++) {
			count += a[i] / mid;
		}
		if (count >= k) {
			res = mid;
			left = mid + 1;
		}
		else if (count<k) {
			right = mid - 1;
		}
	}
	cout << res << endl;
	return 0;
}

其实如果没有那两个return 0的语句会RE两个,作者也不知道怎么回事。。。(可能是数据比较恶心)

http://www.dtcms.com/a/108289.html

相关文章:

  • 如何对后端API进行负载测试
  • vue将组件中template转为js
  • codeforces C. Creating Keys for StORages Has Become My Main Skill
  • systemd服务开机启动(code=exited, status=203/EXEC)错误,由于SELinux 开启安全模式
  • AI知识补全(十五):AI可解释性与透明度是什么?
  • 详细说明一下C++中的static关键字
  • 火山引擎coze用户市场
  • 使用PyTorch实现GoogleNet(Inception)并训练Fashion-MNIST
  • 【华为OD技术面试真题 - 技术面】- Java面试题(17)
  • 移动端六大语言速记:第1部分 - 基础语法与控制结构
  • 网络安全协议知识点总结
  • 网络空间安全(49)Python基础语法
  • 三.微服务架构中的精妙设计:服务注册/服务发现-Eureka
  • JavaScript reduce 方法详解
  • 视图函数的应用
  • 数据仓库项目启动与管理
  • App与Page构造器
  • vim的操作
  • Java面试31-MySQL如何解决幻读问题?
  • 【HTB】Linux-Shocker靶机渗透
  • 人工智能基础知识笔记七:随机变量的几种分布
  • Font Awesome 音/视频图标
  • 程序代码篇---Arm汇编语言
  • Laravel 中使用 JWT 作用户登录,身份认证
  • vue开始时间小于等于结束时间,且开始时间小于等于系统时间,时间格式:年月日时分
  • Python每日一题(13)
  • 【算法进阶详解】线段树应用
  • 洛谷题单2-P2433 【深基1-2】小学数学 N 合一-python-流程图重构
  • 脑影像分析软件推荐 | CONN
  • Django接入 免费的 AI 大模型——讯飞星火(2025年4月最新!!!)