木材加工(二分)

题目名字 木材加工

题目链接

题意

一共有n个木头,然后要将他们截成m个相等长度的木头,求能截的最大的木头的长度

思路

  1. 循环输入这个木头
  2. 进行二分,在二分模板里面进行判断,定义ans来计数,利用每个木头来除mid,用ans来进行统计这些木头被截成mid长度能被截多少段,如果大于等于m,就使边界往右移,如果,小于就往左,就能找到最大的能截得的木头长度了

算法一:二分

代码
 
 #include<iostream>
#include<algorithm> 
using namespace std;
	int n,k;
const int N=1e5+5;
	int a[N];
	int ans=0;
	int find(int l,int r)
	{ while(l<=r){
		int mid=l+r>>1;
		int ans=0;
		for(int i=0;i<n;i++){
			ans+=a[i]/mid;
		}
		if(ans>=k){
			l=mid+1;
		}
		else{
			r=mid-1;
		}
		
	}
	return r;
	}
int main(){
	cin>>n>>k;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);
	int l=1,r=a[n-1];
	int x=find(l,r);
	cout<<x;
	return 0;
}

算法二:二分

思路

通过find二分来找范围内最大的函数,先定义全局变量,数组和输入的n,k,再用find函数进行查找l和r,进行for循环遍历每一个木棍进行计算在不同的mid之下可以切割的木头数量,并且用ans来计数,确保输出的在k范围之内,接下去就是while循环,在(l<=r)范围内进行二分查找,(注意ans要定义在while函数上面,保证每次遍历ans都要初始化,否测ans在每一次遍历上一直叠加),用一个result来记录最大值,返回最大值即return result;
|
ps:为什么不需要再条件ans要小于k呢,是由于二分查找已经包含这个判断啦,ans大于k时范围就会往左移动,所以直接return最大值就好啦,要是超出了给定范围,这个值是不会被保留哒
|
主函数部分主要呢,就是注意用sort函数来遍历一遍所有数组,并且要定义一个值来调用find函数,就OK了
还有调用find函数可以不用定义l和r的值,直接在定义值的时候,在find函数中输入l和r的值即可

代码
#include<iostream>
#include<algorithm>
using namespace std;
const int  N=1e5+5;
int n,k;
int a[N];

int find (int l,int r)
{
	int result=0;
	while(l<=r){
		int mid=l+r>>1;
		int ans=0; 
		for(int i=0;i<n;i++){
			ans+=a[i]/mid; 
		}
		if(ans>=k){
			result=mid;
			l=mid+1;
		}
		else{
			r=mid-1;
		}
	}
	
	return result;
		
}
int main(){
	cin>>n>>k;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);
	int l=1,r=a[n-1];
	int x=find(1,r);
	cout<<x; 
	return 0;
} 

总结

主要是复习了一遍二分,关于各个函数的调用还有用法,不同代码存在的理解,基本没有大问题,如果有一天又忘记了,请看笔记谢谢。这道题还要注意r的范围是a[n-1],最大的那个数字,就是最大的范围边界,考试的时候拜托一定想起来啊啊啊

木材加工二分法在计算机科学领域通常指的是一种在数据结构和算法中寻找特定值的策略,例如在有序数组中查找目标元素的位置。这其实是一个经典的搜索算法问题,与木材加工行业的实际应用并无直接关联。然而,我们可以用“木材加工二分法”这个比喻性描述来说明一种高效的算法思路。 在 C++ 中实现这种类似于二分查找的过程,我们可以构建一个函数,该函数接收一个已排序的整数数组和目标值作为输入,并返回目标值在数组中的索引位置。如果目标值不存在于数组中,则返回一个特定值表示未找到(通常是 -1 或数组长度)。以下是具体的 C++ 实现: ```cpp #include <iostream> using namespace std; // 二分查找函数 int binarySearch(int arr[], int l, int r, int x) { if (r >= l) { int mid = l + (r - l) / 2; // 防止溢出 // 如果中间元素就是你要找的目标 if (arr[mid] == x) return mid; // 如果目标元素小于中间元素,它一定在左侧子数组中 if (arr[mid] > x) return binarySearch(arr, l, mid - 1, x); // 否则目标元素在右侧子数组中 return binarySearch(arr, mid + 1, r, x); } // 目标不在数组中 return -1; } // 主函数用于测试 int main() { int arr[] = {2, 4, 6, 8, 10}; int n = sizeof(arr)/sizeof(arr); int x = 6; int result = binarySearch(arr, 0, n-1, x); if(result != -1) cout << "Element found at index: " << result; else cout << "Element not found"; return 0; } ``` 在这个例子中,“二分法”实际上指的是将大的问题分解成两个更小的子问题,每次解决子问题,逐步缩小问题规模直到找到解。这种方法在大数据处理和优化搜索性能方面非常有效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值