- 木材加工
P2440.木材加工 讲解
- 2025-3-7 19:50:26 @
题目分析
测试用例分析
$$当到了114, 232/114 = 2段,124/114 = 1段,456/114 = 4,2+1+4=7;满足条件 $$$$当到了115, 232/115 = 2段,124/115 = 1段,456/115 = 3段 2+1+3=6,不满足 $$边界分析
如果是l<=r 会导致无限循环
如l=5, r=6 mid = 5,若此时需要向右(l=mid),则 l = mid 会导致 l 还是5,无法跳出循环
为了避免相邻 就需要l+1<r 此时如果r=6,l最多等于4 避免相邻导致死循环
思路分析
二分
0.定义
#include<bits/stdc++.h>
using namespace std;
#define int long long
int s,n;
int a[9000000];
int l=0,r=1e8;//题目规定
signed main(){//前面define int long long
cin>>n>>s;
for(int i=0;i<n;i++ ){
cin>>a[i];
}
while(l+1<r){//循环在l和r相邻时终止 也可以确保最小值为1,讲解见上(边界分析)
int mid=(l+r)/2;
int sum=0;
}
}
1.找最大值
for(int i=0;i<n;i++){
sum+=a[i]/mid;//作用是计算当每个元素被分割为mid个时,所有元素总共能分割出的份数之和
}
2.判断k
if(sum<s)
{
r=mid;
}
else
{
l=mid;
}//l始终指向此时的最大值,而 r 指向最小的值。最终 l(最大值) 即为答案。
3.输出
cout<<l;
题解
#include<bits/stdc++.h>
using namespace std;
#define int long long
int s,n;
int a[9000000];
int l=0,r=1e8;
signed main(){
cin>>n>>s;
for(int i=0;i<n;i++ ){
cin>>a[i];
}
while(l+1<r){//循环在l和r相邻时终止 也可以确保最小值为1
int mid=(l+r)/2;
int sum=0;
for(int i=0;i<n;i++){
sum+=a[i]/mid;
}
if(sum<s){l l始终指向此时的最大值,而 r 指向最小的值。最终 l(最大值) 即为答案。
r=mid;
}
else{
l=mid;
}
// sum=0;
}
cout<<l;
return 0;
}
1行代码解决h_h
```cpp
long long s,n,sum=0,a[9000000],l=0,r=1e8,mid;signed main(){__builtin_scanf("%d %d",&n,&s);for(int i=0;i<n;i++) __builtin_scanf("%d",&a[i]);while(l+1<r){mid=(r+l)/2;for(int i=0;i<n;i++) sum+=a[i]/mid;if(sum<s) r=mid,sum=0;else l=mid,sum=0;}__builtin_printf("%d",l);}
1 comments
-
h_h LV 5 MOD @ 2025-3-7 19:52:38Edited
我感觉你还没有理解问题边界。木材加工发个题解或者讨论说说思路,为什么不用教的模板,如果要用mid+1-1这种写法,请给一篇面对四种情况的可行性严格证明。
- 1
Information
- ID
- 999
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 50
- Accepted
- 13
- Uploaded By