#include <cstdio>
#include <algorithm>
using namespace std;
int loc[100005];
int main()
{
int tc;
scanf("%d",&tc);
while(tc--)
{
int s,h,i,lo,hi,mid;
scanf("%d %d",&s,&h);
for(i=0;i<h;i++)
scanf("%d",&loc[i]);
sort(loc,loc+h);
lo=0;
hi=2*(loc[h-1]-loc[0]+1);
while(hi>lo)
{
mid=(lo+hi)/2;
int start=loc[0];
int needed=1;
for(i=1;i<h;i++)
if(loc[i]>start+mid)
{
needed++;
start=loc[i];
}
if(needed>s)
lo=mid+1;
else
hi=mid;
}
printf("%.1f\n",hi/2.00);
}
return 0;
}
这里hi、lo不断夹进,mid就是直径
每次确定一对hi、lo,就检验mid:
从第一个节点,增加一个mid的长度,再找到下一个不在该长度内的节点;
再以这个节点,增加一个mid……
直到节点找完为止,用needed记录需要的路由器,与s比较
如果needed>s,说明mid小了,那么mid的下限(lo)就大于mid,也就是mid+1
如果needed<=s,说明mid大了,那么mid的上限(hi)就重置为mid
这样,我们就可以一步步逼近正确答案的范围,知道hi=lo
心得,二分法最重要的不是模板(二分法入门那一篇博客),而是找到正确答案的hi是谁,lo是谁,mid就是正确答案,还要找到检验mid的方法,这里就是needed与s的比较,而入门的那一篇里,是拿mid与key值是否相等……