51nod 1247 可能的路径 -数论

来源:互联网 发布:中文分词算法 hanlp 编辑:程序博客网 时间:2024/05/18 02:29

链接:1247

站在(a,b)点上,下一步你可以移动到(a + b, b), (a, a + b), (a - b, b), 或者 (a, a - b)这4个点。

进行推导:

(a,b)->(a ,a-b)->(a-(a-b),a-b)=(b,a-b)->(b,a)  ∴ (a,b)能到(b,a)

(a,b)->(a+b,b)......->(a+kb,b)

(a,b)->(a-b,b)......->(a%b,b)


由1和3可知(a,b)->(a%b,b)->(b,a%b)->(b%(a%b),a%b)......->(c,0) 辗转相除法,这里c是a,b的最大公约数

也就是说(a,b)一定能到达(c,0)和(0,c)。

由2,假设a=uc,b=vc,u>v

(0,c)->(kc,c)->(kc,nkc).....(uc,vc)=(a,b) 就是辗转相除法的倒推


也就是说从任意一点(a,b)一定能抵达(c,0),并且也能返回(a,b)。

如果两个点都能到达(c,0),则两个点一定能连通。

能力有限我无法严格证明两个点只要连通就一定都能访问到(c,0),但这题的数据中并没有给出反例,也就是说我们只需要验证两个点是不是都能同时抵达(c,0)就行,也就是判断两个点坐标的最大公约数是否相等 。

代码:

#include<iostream>using namespace std;long long gcd(long long a,long long b){   if(a%b==0)return b;   else return gcd(b,a%b);}int main(){   long long a,b,c,d;   int n;   cin>>n;   while(n--){      cin>>a>>b>>c>>d;      if(gcd(a,b)==gcd(c,d))cout<<"Yes"<<endl;      else cout<<"No"<<endl;   }}