题目连接:http://www.careercup.com/question?id=5697293959299072
A robot has to move in a grid which is in the form of a matrix. It can go to
1.) A(i,j)--> A(i+j,j) (Down)
2.) A(i,j)--> A(i,i+j) (Right)
Given it starts at (1,1) and it has to go to A(m,n), find the minimum number of STEPS it has to take to get to (m,n) and write
public static int minSteps(int m,int n)
For instance to go from (1,1) to m=3 and n=2 it has to take (1, 1) -> (1, 2) -> (3, 2) i.e. 2 steps
题目翻译:一个机器人在以个二维网格中移动,它可以以两种方式移动:
(1) 从(i, j)走到(i+j, j)
(2) 从(i, j)走到(i, i+j)
机器人现在从(1, 1)出发,问他一共需要多少步才能走到(m, n),例如从(1, 1)走到(3, 2)需要2步:(1, 1) -> (1, 2) -> (3, 2)
题目分析:
由(1)(2)两种移动方式可知,如果机器人当前位于某一位置(i, j):
(1)i > j,则机器人必然是从(i-j, j)以第一种方式移动过来的,因为从任意位置以第二种方式移动,下一位置的y坐标肯定比x坐标大
(2)同样的,i < j,则机器人必然是从(i, j-i)以第二种方式移动过来的
所以很容易得到:
int minSteps(int x, int y)
{
if(x == 1) return y-1;
if(y == 1) return x-1;
if(x > y) return minSteps(x-y, y) + 1;
else return minSteps(x, y-x) + 1;
}
如果当前位置是(10, 2)呢,则上一位置是(8, 2),再上一位置是(6, 2),再上一位置(4, 2),再上一位置是(2, 2),然后呢?
我们发现走不通了,看起来(10, 2)这个位置根本走不通呢,因为连(2, 2)这个位置都到不了,那到底哪些位置走不通呢?
因为移动方式只有(1)(2)两种,如果一个坐标是1,则另外一个坐标可以是任意值,如果两个坐标都不是1呢,经过(1)(2)两步推回去,如果得到x == y了,则不可能到达,所以我们有:
int minSteps(int x, int y)
{
if(x == 1) return y-1;
if(y == 1) return x-1;
if(x == y) return -1;
int res = x > y ? minSteps(x-y, y) : minSteps(x, y-x);
if(res == -1) return -1;
else return res + 1;
}
如果当前位置是(7, 2)呢,则上一步是(5, 2),再上一步是(3, 2),再上一步是(1, 2),我们发现我们连续以第一种方式走了3步,直到x坐标小于等于y坐标,所以
(1)如果当前位置是(x, y)且x > y,则是从(x % y, y)以第一种方式走了x / y步到达的
(2)同理,如果当前位置(x, y)且x < y,则是从(x, y % x)以第一种方式走了y / x步到达的
(3)如果我们逆推到某一位置发现x == y,则上一位置肯定有x % y == 0或者y % x == 0,毕竟上一位置只可能是(x+y, y)或者(x, x+y),即(2y, y)或者(x, 2x)
所以,我们可以得到
int minSteps(int x, int y)
{
if(x < 1 || y < 1) return -1;
if(x == 1) return y-1;
if(y == 1) return x-1;
if(x % y == 0 || y % x == 0) return -1;
int steps = 0;
while(x != 1 && y != 1){
if(x > y){
steps += x / y;
x %= y;
}
else{
steps += y / x;
y %= x;
}
}
if(x == 1) steps += y-1;
else if(y == 1) steps += x-1;
return steps;
}