题目分析

n个木材平均分成m份,每份要一样,问每份最多多少将n个木材平均分成m份,每份要一样,问每份最多多少

测试用例分析

$$当到了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

  • @ 2025-3-7 19:52:38

    我感觉你还没有理解问题边界。木材加工发个题解或者讨论说说思路,为什么不用教的模板,如果要用mid+1-1这种写法,请给一篇面对四种情况的可行性严格证明。

  • 1

Information

ID
999
Time
1000ms
Memory
256MiB
Difficulty
7
Tags
# Submissions
50
Accepted
13
Uploaded By