[51Nod] (1247) 可能的路径 ---- 思维+欧几里得

题目传送门

思路:

  • 求解的时候,往扩展gcd的方向去了QAQ,WA 3 放弃
  • 看到一个巨巨的神之推导。
  • (a+b,b) ,(a-b,b),(a,a-b),(a,a+b) 这四个方向都可以推到(a,b)。(证明可逆)
  • 例如: (a,a-b) -> (a-(a-b),a-b) -> (b,a-b) -> (b,a-b+b) -> (b,a) -> (b+a,a) -> (b+a,b+a-a) ->(b+a,b) -> (b+a-b,b) - >(a,b)
  • 中间过程中出现了(b,a) 证明 (a,b) 可以推到(b,a)
  • 那么(a-b,b) -> (a-b-b,b) ->(a-3b,b) -> …… -> (a-nb,b) ,n = a/b
  • 就转化为 (a%b,b) -> (b,a%b) 即欧几里得算法的过程。
  • 题目就变成了是否存在一个点(m,n),使得(a,b)通过转换能到达,(x,y)通过转换也能到达,如果存在,证明(a,b)与(x,y) 之间存在通路。

AC代码:

#include
using namespace std;

#define IO          ios_base::sync_with_stdio(0),cin.tie(0)
#define pb(x)       push_back(x)
#define sz(x)       (int)(x).size()
#define abs(x)      ((x) < 0 ? -(x) : x)
#define mk(x,y)     make_pair(x,y)
#define fin         freopen("in.txt","r",stdin)
#define fout        freopen("out.txt","w",stdout)

typedef long long ll;
typedef pair<int,int> P;
const int mod = 1e9+7;
const int maxm = 1e8+5;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
const ll LINF = 1ll<<62;

//void exgcd(ll a,ll b,ll &x,ll &y,ll &d)
//{
//    if(!b) d = a,x = 1,y = 0;
//    else exgcd(b,a%b,y,x,d), y -= (a/b)*x;
//}
ll gcd(ll a,ll b)
{
   return b?gcd(b,a%b):a;
}
int main()
{
//    fin;
   IO;
   int t;
   cin>>t;
   while(t--)
   {
       ll a,b,xx,yy;
       cin>>a>>b>>xx>>yy;
       if(gcd(a,b) == gcd(xx,yy)) cout<<"Yes"<<endl;
       else cout<<"No"<<endl;
   }
   return 0;
}

你可能感兴趣的:(【数学】,【思维】)