如果限定矩形的边长必须为整数,且周长为定值L,那么面积在[A, B]范围内不同的矩形一共有多少个呢?
在这个问题中,当且仅当两个矩形面积不同时,视作是两个不同的矩形。
输入数据的第一行包含一个整数T (1 <= T <= 10000),表示接下来一共有T组测试数据。
对于每组测试数据,包含三个整数L (1 <= L <= 2,000,000,000)、A、B (1 <= A <= B <= 250,000,000,000,000,000),含义同上。
对于每组测试数据,用一行输出一个整数,代表上述问题的答案。
11 1 6
12 5 10
12 8 10
32 64 100
32 20 70
32 20 64
32 20 10
3
2
1
7
7
7
题意:
中文题目
题解:
依照题目的数据可以明显的看出需要公式推导,或者二分才能解出数据范围如此之大的
方法一:
公式推导:
假设某一条边长为 x ,另外一条边长为 L/2 - x
面积就是 y = ( L/2 - x ) * x ,是一个开口朝下的函数
求这个函数与y = a 和 y = b 两条线的交点 , 通过交点然后可以求出解空间,最后得到答案
这里需要注意的就是小数化整数的时候,详细的处理见代码
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
#define eps 1e-6
int main()
{
int T;
LL l,a,b;
//freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&l,&a,&b);
if(l%2){
puts("0");
continue;
}
l/=2;
double x1,x2;
if(l*l-4*a<0)
puts("0");
else if(l*l-4*b<0){
x1=(l*1.0-sqrt(l*l-4*a))/2;
if(x1-(LL)x1<eps)
x1--;
printf("%lld\n",l/2-(LL)x1);
}else{
x1=(l-sqrt(l*l-4*b))/2;
x2=(l-sqrt(l*l-4*a))/2;
if(x2-(LL)x2<eps)
x2--;
printf("%lld\n",(LL)x1-(LL)x2);
}
}
return 0;
}
方法二:
两次二分
二分函数y与直线 y=a 最小的交点
二分函数y与直线 y=b 最小的交点
然后两值一减就是答案了
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
int main()
{
int T;
LL l,a,b;
freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&l,&a,&b);
if(l%2){
puts("0");
continue;
}
l/=2;
LL x1=0,x2=0;
LL left=1,right=l/2,mid;///二分的范围1到中位线
while(left<=right)
{
mid=(left+right)>>1;
if(mid*(l-mid)<a){
x1=max(x1,mid);
left=mid+1;
}
else
right=mid-1;
}
left=1,right=l/2;
while(left<=right)
{
mid=(left+right)>>1;
if(mid*(l-mid)<=b){
x2=max(x2,mid);
left=mid+1;
}
else
right=mid-1;
}
printf("%lld\n",x2-x1);
}
return 0;
}