题目:
题意:
在一个 n ∗ m n*m n∗m的大矩形中,我们需要等距离放置若干个边长为 l l l的正方形,问间隔最少是多少
分析:
考场上的暴力居然愉快切了,真是效率飞起
设横着有
a
a
a个正方形,竖着有
b
b
b个正方形,会有
a
∗
l
+
(
a
+
1
)
x
=
n
、
b
∗
l
+
(
b
+
1
)
x
=
m
a*l+(a+1)x=n、b*l+(b+1)x=m
a∗l+(a+1)x=n、b∗l+(b+1)x=m
将两个式子两边都
+
l
+l
+l,将
a
+
1
a+1
a+1用换元法变成
a
a
a,
b
b
b也是同理,就有
a
(
l
+
x
)
=
n
+
l
、
b
(
l
+
x
)
=
m
+
l
a(l+x)=n+l、b(l+x)=m+l
a(l+x)=n+l、b(l+x)=m+l,把两边的
a
、
b
a、b
a、b移过去,就有
n
+
l
a
=
m
+
l
b
\frac{n+l}{a}=\frac{m+l}{b}
an+l=bm+l,这样两边的最大值是他们的
g
c
d
gcd
gcd
此时
x
=
g
c
d
−
l
x=gcd-l
x=gcd−l,如果会是一个负数,显然无解
有解的情况下,需要找到一个
k
k
k,满足
(
k
+
1
)
∗
g
c
d
>
l
,
k
∗
g
c
d
<
=
l
(k+1)*gcd>l,k*gcd<=l
(k+1)∗gcd>l,k∗gcd<=l,此时
x
x
x就是最小的
代码:
//是暴力哒,正解不想敲了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#include<map>
#include<ctime>
#define LL long long
using namespace std;
inline LL read()
{
int s=0,f=1; char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {s=s*10+c-'0';c=getchar();}
return s*f;
}
int main()
{
int l=read(),n=read(),m=read();
int b; double x;
for(int a=n/l;a;a--)
{
x=(double)(n-a*l)/(a+1);
int b1=a,b2=a;
int tf=1;
while(tf)
{
tf=0;
if(b1)
{
if(x==(double)(m-b1*l)/(b1+1)) return !printf("%.5lf",x);
tf=1;
b1--;
}
if(b2<=m/l)
{
if(x==(double)(m-b2*l)/(b2+1)) return !printf("%.5lf",x);
tf=1;
b2++;
}
}
}
printf("-1");
return 0;
}