hdu2965 Business Cards

链接

http://acm.hdu.edu.cn/showproblem.php?pid=2965

题解

这题多少有点瞎猜的意思
如果全都横着放,那就要求 a c , b d a|c,b|d
都竖着放,就要求 b c , a d b|c,a|d
否则就有的横着有的竖着,但是绝对不会交叉,就是可以这样
在这里插入图片描述
但是不会这样
在这里插入图片描述
(不知道我说清楚了没有)
容易发现,有一条边必须是 l c m ( a , b ) lcm(a,b) 的整数倍
另一条边等于 k 1 a + k 2 b k_1a+k_2b ,直接用扩展欧几里德去解一个方程就好了

代码

//ÊýѧÌâ 
#include <bits/stdc++.h>
#define ll long long
using namespace std;
void exgcd(ll a, ll b, ll &x, ll &y)
{
	ll xx, yy;
	if(!b){x=1, y=0;return;}
	exgcd(b,a%b,xx,yy);
	x=yy, y=xx-a/b*yy;
}
ll gcd(ll a, ll b){return !b?a:gcd(b,a%b);}
bool solute(ll a, ll b, ll c, ll &x, ll &y)
{
	ll g=gcd(a,b);
	if(c%g!=0)return false;
	exgcd(a,b,x,y);
	x*=c/g, y*=c/g;
	return true;
}
bool judge(ll a, ll b, ll c, ll d)
{
	ll x, y, lcm, g, xx, yy, t, m;
	if(c%a==0 and d%b==0 or c%b==0 and d%a==0)return true;
	lcm=a*b/(g=gcd(a,b));
	if(d%lcm==0)
	{
		if(solute(a,b,c,xx,yy))
		{
			m=b/gcd(a,b);
			x=((xx%m)+m)%m;
			t=(x-xx)/m;
			m=a/gcd(a,b);
			y=yy-t*m;
			if(x>=0 and y>=0)return true;
		}
	}
	if(c%lcm==0)
	{
		if(solute(a,b,d,xx,yy))
		{
			m=b/gcd(a,b);
			x=((xx%m)+m)%m;
			t=(x-xx)/m;
			m=a/gcd(a,b);
			y=yy-t*m;
			if(x>=0 and y>=0)return true;
		}
	}
	return false;
}
int main()
{
	ll a, b, c, d, t;
	scanf("%lld",&t);
	while(t--)
	{
		scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
		if(judge(a,b,c,d))printf("YES\n");
		else printf("NO\n");
	}
	return 0; 
}

猜你喜欢

转载自blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/83240752