这道题啊,我首先没想着用二分,(确切是没想起来。。)而是想看看有什么数学规律,什么最长的和第二长的关系啊,等等,发现并没有用,然后我就想起来用二分做这道题,这个题复杂度为NLOGN级别的,LOGN就是二分次数,每次二分后FOR循环判断一下这个数的个数。另外:这道题二分的模板是我根据题目来写的,应该有一个自己常用的模板才好
#include<iostream> #include<string> #include <algorithm> #include <cstdio> #include<math.h> using namespace std; int a[200002];//开这个全局数组少传一个参数,不用借助指针作为中介取值, void digui(int n,int k) { int tem,max,w,j,sum,l; sort(a,a+n);//sort一定要摆在前面,我用DEVC++断点调试才找出这错误。 l=0; max=0; sum=0; w=a[n-1]; tem=w+l; while(1) { for(j=n-1;j>=0;j--) { sum+=(a[j]/tem); } if(sum<k) { w=tem;//字面意思理解,代码是通俗易懂的,右端点变成该值(因为此值较大,分不成所需要的份数) tem=(tem+l)/2; } if(sum>=k)//这个数小了,要把它往前提。 { l=tem; if(tem>max)max=tem;//注意这一句话和下一句话的顺序,影响取值。 tem=(tem+w)/2; } sum=0;if(tem==l||tem==w)break;//l或者w之前已经判断过了,所以相等了就退出即可, }cout<<max<<endl; } int main() { int n,k; cin>>n>>k; int t; for(t=0;t<n;t++) { cin>>a[t]; } digui(n,k); system("pause"); return 0; }