Description

A move consists of taking a point (x, y) and transforming it to either (x, x+y) or (x+y, y).

Given a starting point (sx, sy) and a target point (tx, ty), return True if and only if a sequence of moves exists to transform the point (sx, sy) to (tx, ty). Otherwise, return False.


Examples:
Input: sx = 1, sy = 1, tx = 3, ty = 5
Output: True
Explanation:
One series of moves that transforms the starting point to the target is:
(1, 1) -> (1, 2)
(1, 2) -> (3, 2)
(3, 2) -> (3, 5)

Input: sx = 1, sy = 1, tx = 2, ty = 2
Output: False

Input: sx = 1, sy = 1, tx = 1, ty = 1
Output: True

 


Note:

  • sx, sy, tx, ty will all be integers in the range [1, 10^9].

问题描述

一步为将(x, y)转换为(x + y, y)或者(x, x + y)

给定起始点(sx, sy)和终点(tx, ty),如果经过一系列的移动能从起点到终点,返回true,否则返回false


问题分析

从(x, y)出发可以到达的点的可能性非常多,而从(tx, ty)倒着推只有一条路
即,若tx > ty, tx = tx % ty,否则,ty = ty % tx

举个例子

tx = 5, ty = 7
由于tx < ty,上一轮肯定是(x, x + y),因此ty = ty %tx = 2
依次类推,可以得到初始点为(1, 2)

思路

当tx > sx 且 ty > sy时,将tx和ty倒推
若tx = sx 且 (ty - sy) % sx == 0 或者 ty == sy 且 (tx - sx) % sy ==0 .返回true


解法

class Solution {
    public boolean reachingPoints(int sx, int sy, int tx, int ty) {
        while(tx > sx && ty > sy){
            if(ty < tx) tx %= ty;
            else        ty %= tx;
        }

        if(sx == tx){
            return (ty - sy) % sx == 0;
        }else if(sy == ty){
            return (tx - sx) % sy == 0;
        }

        return false;
    }
}

 

 1 //C++
 2 class Solution {
 3 public:
 4     bool reachingPoints(int sx, int sy, int tx, int ty) {
 5         if(tx==sx&&ty==sy)
 6         return true;
 7         if(tx==ty||tx==0||ty==0)
 8         return false;
 9         if(ty>tx)
10             return reachingPoints(sx, sy, tx, ty-max((ty-sy)/tx,1)*tx);
11         if(tx>ty)
12             return reachingPoints(sx, sy, tx-max((tx-sx)/ty,1)*ty, ty);   
13         return false;
14     }
15 };

 

  1 #include <stdio.h>
  2 #include <math.h>
  3 
  4  
  5 #if 1
  6 #define MY_print_ln_E(fmt, arg...)       { if (1 <= g_log_level) {printf("(%s|%d)" fmt"\r\n", __func__, __LINE__, ##arg);} }
  7 #define MY_print_ln_W(fmt, arg...)       { if (2 <= g_log_level) {printf("(%s|%d)" fmt"\r\n", __func__, __LINE__, ##arg);} }
  8 #define MY_print_ln_I(fmt, arg...)       { if (3 <= g_log_level) {printf("(%s|%d)" fmt"\r\n", __func__, __LINE__, ##arg);} }
  9 #define MY_print_ln_D(fmt, arg...)       { if (4 <= g_log_level) {printf("(%s|%d)" fmt"\r\n", __func__, __LINE__, ##arg);} }
 10 #else
 11 #define MY_print_ln_E(fmt, arg...)       {  }
 12 #define MY_print_ln_W(fmt, arg...)       {  }
 13 #define MY_print_ln_I(fmt, arg...)       {  }
 14 #define MY_print_ln_D(fmt, arg...)       {  }
 15 #endif
 16 #define false    (0)
 17 #define true     (1)
 18 
 19 static int g_log_level = 3;
 20 
 21 int max(int a, int b)
 22 {
 23     return  a > b ? a : b;
 24 }
 25 
 26 /**********************************************************************************************
 27         坐标点移动能力测试
 28 
 29     **** 坐标在第一象限移动 ****
 30 
 31     日期: 2020.09.28 21:00:00
 32     作者: LiuYan
 33 
 34     参数: 
 35         sx, 起始点横坐标
 36         sy, 起始点纵坐标
 37         tx, 起始点横坐标
 38         ty, 起始点纵坐标
 39 
 40     返回值: 1能移动到目标坐标, 0不能移动到目标坐标
 41 
 42 **********************************************************************************************/
 43 int move_from_to(int sx, int sy, int tx, int ty)
 44 {
 45     int tmp_x = 0;
 46     int tmp_y = 0;
 47     int move_who = 0; // 0为x, 1为y
 48     int n = 0;
 49 
 50 
 51     MY_print_ln_D("judge from=(%d, %d), to=(%d, %d)\r\n", sx, sy, tx, ty);
 52 
 53     for (tmp_x = tx, tmp_y = ty; !(tmp_x < sx && tmp_y < sy); )
 54     {
 55 
 56         if (tmp_x == sx && tmp_y == sy)
 57         {
 58             MY_print_ln_I("move (%d, %d)->(%d, %d), Success", sx, sy, tx, ty);
 59             return true;
 60         }
 61 
 62         if (tmp_x == tmp_y || 0 == tmp_x || 0 == tmp_y)
 63         {
 64             MY_print_ln_I("move (%d, %d)->(%d, %d), Failed, last_point=(%d, %d)", sx, sy, tx, ty, tmp_x, tmp_y);
 65             return false;
 66         }
 67 
 68         move_who = (tmp_y > tmp_x) ? 1 : 0;
 69 
 70         if (0 == move_who)  // 移动x
 71         {
 72             n = (tmp_x-sx)/tmp_y;
 73             n = n < 1 ? 1 : n;
 74 
 75             tmp_x -= n * tmp_y;
 76         } 
 77         else // 移动y
 78         {
 79             n = (tmp_y-sy)/tmp_x;
 80             n = n < 1 ? 1 : n;
 81 
 82             tmp_y -= n * tmp_x;
 83         }
 84 
 85         MY_print_ln_D("move_who=%d, (%d, %d)", move_who, tmp_x, tmp_y);
 86         
 87     }
 88 
 89     MY_print_ln_I("move (%d, %d)->(%d, %d), Failed, last_point=(%d, %d)", sx, sy, tx, ty, tmp_x, tmp_y);
 90     return false;
 91 }
 92 
 93 int main(int argc, char *argv[])
 94 {
 95     // 成功测试用例
 96     MY_print_ln_I("%d", move_from_to(1, 2, 5, 2));
 97     MY_print_ln_I("%d", move_from_to(2, 3, 2, 9));
 98     MY_print_ln_I("%d", move_from_to(1, 2, 3, 5));
 99     MY_print_ln_I("%d", move_from_to(1, 2, 3, 8));
100     MY_print_ln_I("%d", move_from_to(1, 2, 11, 8));
101     MY_print_ln_I("%d", move_from_to(1, 2, 19, 8));
102     MY_print_ln_I("%d", move_from_to(1, 2, 27, 8));
103 
104     // 失败测试用例
105     MY_print_ln_I("%d", move_from_to(1, 2, 27, 9));
106     return 0;
107 }