这道题啊,我首先没想着用二分,(确切是没想起来。。)而是想看看有什么数学规律,什么最长的和第二长的关系啊,等等,发现并没有用,然后我就想起来用二分做这道题,这个题复杂度为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;
}
京公网安备 11010502036488号