当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度:
Hard

题意:

  1. 给定一个点对(x,y),每次操作可以变换成(x,x+y)或者(x+y,y)
  2. 给定两个点对(sx, sy),和(tx, ty),问能否通过任意次操作,使前一个点对可以变换成后一个点对

思路:

  • 我们反正来,如果得到一个点对(x,y),最有可能是从哪些点对来的
  • 假设tx<ty,反之亦然
  • 那么点对可以从(tx,ty),(tx, ty-tx),(tx,ty-k*tx)。。。得来的
  • 我们可以得出一个递归方式
  • 如果sx>tx,直接返回false,因为sx不管怎么变换,都不能比sx小
  • 如果sx=tx,判断(ty-sy)是否不小于0,并且可以被sx整除
  • 如果sx<tx,那么我们需要判断(sx, sy)和(tx, ty % tx)是否可以变换
  • 这个算法叫做辗转相除法,也叫欧几里得算法,计算最大公约数也是这个算法

解法:

  1. class Solution {
  2. private boolean solve(int sx, int sy, int tx, int ty) {
  3. if (tx < ty) {
  4. if (tx < sx) {
  5. return false;
  6. }
  7. if (tx == sx) {
  8. if (ty >= sy && (ty - sy) % sx == 0) {
  9. return true;
  10. } else {
  11. return false;
  12. }
  13. }
  14. return solve(sx, sy, tx, ty % tx);
  15. } else {
  16. if (ty < sy) {
  17. return false;
  18. }
  19. if (ty == sy) {
  20. if (tx >= sx && (tx - sx) % sy == 0) {
  21. return true;
  22. } else {
  23. return false;
  24. }
  25. }
  26. return solve(sx, sy, tx % ty, ty);
  27. }
  28. }
  29. public boolean reachingPoints(int sx, int sy, int tx, int ty) {
  30. return solve(sx, sy, tx, ty);
  31. }
  32. }

该分类下的相关小册推荐: