—对于某些问题,如果答案具有特定的范围,并且验证答案是否成立的函数具有单调性。
则可以在范围内对答案进行二分验证,从而快速确定答案。
例:hdu 1969
这题的关键在与对范围进行变换,因为我们一般所遇到的二分都是整数,进行mid+1或mid-1,所以对数字*误差容许的数量级。
具体代码如下:
|
#
include
<cstdio>
#
include
<cstring>
#
include
<algorithm>
#
include
<cmath>
#define LL long long
#define pi
2
*asin(
1.0
)
using
namespace
std;
int
n;
LL a[
10010
];
int
judge(LL x)
{
int
cnt=
0
;
for
(
int
i=
0
;i<n;i++)
{
cnt+=
int
(
1.0
*pi*a[i]*a[i]/x);
}
return
cnt;
}
LL binary_find(
int
m,LL up)
{
up=(LL)(
1.0
*pi*up*up);
LL low=
0
;
while
(low<=up)
{
LL mid=(low+up)/
2
;
int
temp=judge(mid);
//if(temp>=m) return mid;这里不能返回,因为不一定数量相等时最大,精度问题,同一个temp对应对个mid~!!
if
(temp>=m) low=mid+
1
;
else
up=mid-
1
;
}
return
low;
}
int
main()
{
int
t,m;
scanf(
"%d"
,&t);
while
(t--)
{
scanf(
"%d%d"
,&n,&m);
LL maxn=
0
;
for
(
int
i=
0
;i<n;i++)
{
scanf(
"%lld"
,&a[i]);
a[i]=a[i]*
1000
;
maxn=max(maxn,a[i]);
}
printf(
"%.4lf\n"
,(
1.0
*(binary_find(m+
1
,maxn))/
1000000
));
}
return
0
;
}
|