校内测 11.3 T2 堆箱子【数论】


题目:

传送门


题意:

在一个 n ∗ m n*m nm的大矩形中,我们需要等距离放置若干个边长为 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 al+(a+1)x=nbl+(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+lb(l+x)=m+l,把两边的 a 、 b a、b ab移过去,就有 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=gcdl,如果会是一个负数,显然无解
有解的情况下,需要找到一个 k k k,满足 ( k + 1 ) ∗ g c d > l , k ∗ g c d < = l (k+1)*gcd>l,k*gcd<=l (k+1)gcd>lkgcd<=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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值