3 solutions
-
2
#include<iostream> #define int long long using namespace std; int n,k; int a[114514]; int l=1,m=50000000,r=100000000; bool check() { int sum=0; for(int i=0;i<n;i++) { sum+=a[i]/m;//统计最多能分多少 } return sum<k;//返回切的段少了时 } signed main()//用了define { cin>>n>>k;//输入 for(int i=0;i<n;i++) { cin>>a[i];//输入 } while(l<=r)//边界 { m=(l+r)/2;//二分(中分头,背带裤,你是ai kun我记住) if(check())//切的段少了时 { r=m-1;//右移 } else { l=m+1;//左移 } } cout<<l-1;//输出 return 0; }
-
1
测试用例分析
$$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 避免相邻导致死循环
#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
Information
- ID
- 999
- Time
- 1000ms
- Memory
- 128MiB
- Difficulty
- 7
- Tags
- # Submissions
- 50
- Accepted
- 13
- Uploaded By