LG·堆箱子【数论】

2020年11月3日提高组【校测】 luogu U138415 堆箱子

Description–

> l i n k link link

仓库中有很多的箱子,这天小武想把箱子收拾一下。仓库是一个长方体,我们不用考虑仓库的高度,仓库的长度为 N N N,宽度为 M M M,箱子是一个标准的正方体,边长为 L L L。小武很严格,对于箱子的摆放有很严格的要求。小武要求用若干根直线等分仓库的长和宽,而箱子只能放在等分长和宽的直线的交点上,并且一个箱子到四个方向的距离(可能是到另一个箱子, 也可能是到仓库的边缘),必须相同。那么在满足要求的前提下,小武想放心尽可能多的箱子, 那么此时一个箱子到四个方向的距离是多少呢?(设这个距离为 x x x
在这里插入图片描述


Input–

一行三个数表示 L , N , M L,N,M LNM

Output–

一行一个实数表示距离 x x x,精确到小数点后五位,如果无法满足要求,输出 − 1 -1 1


Sample Input–

样例1

2 18 13

样例2

4 26 26

样例3

3 46 18

Sample Output–

样例1

0.50000

样例2

0.28571

样例3

0.50000

说明–

样例解释
对于样例 1 1 1,横排放 7 7 7 个箱子,竖排放 5 5 5 个箱子 :
x = ( 18 − 27 ) / 8 = ( 13 − 25 ) / 6 = 0.50000 x=(18-27)/8=(13-25)/6=0.50000 x=(1827)/8=(1325)/6=0.50000

数据范围
对于 24 % 24\% 24% 的数据, 1 ≤ L ≤ 100 , 1 ≤ N , M ≤ 1000 1≤L≤100,1≤N,M≤1000 1L1001N,M1000
对于 48 % 48\% 48% 的数据, 1 ≤ L ≤ 1000 , 1 ≤ L , N , M ≤ 1 0 6 1≤L≤1000,1≤L,N,M≤10^6 1L10001L,N,M106
对于 80 % 80\% 80% 的数据, 1 ≤ L ≤ 1 0 6 1≤L≤10^6 1L106
对于 100 % 100\% 100% 的数据, 1 ≤ L , N , M ≤ 1 0 9 1≤L,N,M≤10^9 1L,N,M109


解题思路–

将仓库俯视图的长宽分别拓宽 L L L
那么每行每列都是由若干个正方形 + 一条线组成( L L L + 线长 x x x
即长宽分别为 ( L + x ) (L+x) (L+x) 的若干倍
于是问题就转换为求出最小的 ( L + x ) (L+x) (L+x)
也就是使得 ( M + L ) (M+L) (M+L) ( N + L ) (N+L) (N+L) 除以它都能得到整数
那么只要 g = g c d ( M + L , N + L ) g = gcd(M+L,N+L) g=gcd(M+L,N+L) 除以它是整数即可
假设 g L + x = y \frac{g}{L+x}=y L+xg=y,即 g y = L + x \frac{g}{y}=L+x yg=L+x
因为 x > 0 x>0 x>0
所以就是求满足 g y > = L \frac{g}{y}>=L yg>=L 的最大 y y y
所以最大 y y y就是 g L \frac{g}{L} Lg下取整
那么答案就是 g y − L \dfrac{g}{y}-L ygL ( − L (-L (L是因为 g y \frac{g}{y} yg为最小的 ( L + x ) ) (L+x)) (L+x))


代码–

#include <iostream>
#include <cstdio>

using namespace std;

int l, n, m, a;
double ans;

int gcd(int x, int y)
{
	if (!y) return x;
	return gcd(y, x % y);
}

int main()
{
	scanf("%d%d%d", &l, &n, &m);
	a = gcd(n + l, m + l);
	if (n < l || m < l || a < l) printf("-1");
	else printf("%.5lf", (double)a / (a / l) - l);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值