兔八哥与猎人
题目描述
兔八哥躲藏在树林旁边的果园里。果园有 M × N M \times N M×N 棵树,组成一个 M M M 行 N N N 列的矩阵,水平或垂直相邻的两棵树的距离为 1 1 1。兔八哥在一棵果树下。
猎人背着猎枪走进了果园,他爬上一棵果树,准备杀死兔八哥。
如果猎人与兔八哥之间没有其它的果树,猎人就可以看到兔八哥。
现己知猎人和兔八哥的位置,编写程序判断兔子所在的位置是否安全.
输入格式
第一行为 n n n,表示有 n n n 组数据,每组数据的第一行为两个正整数 a x a_x ax 和 a y a_y ay,表示猎人的位置,第二行为两个正整数 b x b_x bx 和 b y b_y by,表示兔八哥的位置。
输出格式
共有
n
n
n 行,每行为 yes
或 no
表示兔八哥的位置是否安全。
样例 #1
样例输入 #1
1
1 1
1 2
样例输出 #1
no
提示
1 ≤ n ≤ 1 0 5 1\le n \le 10^5 1≤n≤105, 1 ≤ a x , a y , b x , b y ≤ 1 0 8 1 \le a_x, a_y, b_x, b_y \le 10^8 1≤ax,ay,bx,by≤108。
思路
我们可以将两个整数 x x x 和 y y y 看作是一个二维平面上的点 ( x , y ) (x, y) (x,y)。如果两点之间存在一个整数点,那么必然是一个整数倍的关系,即存在两个整数 k k k 和 l l l,使得 x = k z x=kz x=kz, y = l z y=lz y=lz,其中 z z z 是 x x x 和 y y y 的最大公约数。因此, x / z x/z x/z 和 y / z y/z y/z 必然不互质。反之,如果 x / z x/z x/z 和 y / z y/z y/z 不互质,则存在两个整数 k k k 和 l l l,使得 x = k z x=kz x=kz, y = l z y=lz y=lz,因此它们之间必然存在一个整数点。
因此,我们只需要计算出 ∣ x − a ∣ |x-a| ∣x−a∣ 和 ∣ y − b ∣ |y-b| ∣y−b∣ 的最大公约数,判断是否为 1 1 1 即可。
注意:输入没有给出 M M M 行 N N N 列,地图视为无限大。
AC代码
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
// 辗转相除法
int gcd(int x, int y)
{
if (x < y)
{
x ^= y ^= x ^= y;
}
if (!y)
{
return x;
}
return gcd(y, x % y);
}
int abs(int x)
{
return (x < 0) ? (-x) : x;
}
int main()
{
int n;
cin >> n;
while (n--)
{
// 猎人位置
int a, b;
// 兔子位置
int x, y;
cin >> a >> b >> x >> y;
if (gcd(abs(x - a), abs(y - b)) != 1)
{
// 不互质,有整数点
cout << "yes" << endl;
}
else
{
cout << "no" << endl;
}
}
return 0;
}