链接
http://acm.hdu.edu.cn/showproblem.php?pid=2965
题解
这题多少有点瞎猜的意思
如果全都横着放,那就要求
a
∣
c
,
b
∣
d
a|c,b|d
a∣c,b∣d
都竖着放,就要求
b
∣
c
,
a
∣
d
b|c,a|d
b∣c,a∣d
否则就有的横着有的竖着,但是绝对不会交叉,就是可以这样
但是不会这样
(不知道我说清楚了没有)
容易发现,有一条边必须是
l
c
m
(
a
,
b
)
lcm(a,b)
lcm(a,b)的整数倍
另一条边等于
k
1
a
+
k
2
b
k_1a+k_2b
k1a+k2b,直接用扩展欧几里德去解一个方程就好了
代码
//ÊýѧÌâ
#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;
}