给定NxM平面,找到两个点之间的所有可能路径,包括三个运动:右,下和对角线(右下,315º)。
我坚持这个问题。我必须通过两种方式解决它:递归和迭代。对于迭代我有想法,但不知道如何实现它。
我的想法的描述是:
(谷歌翻译)。我们面对的是N列宽度和M行高度的板。我们必须从点(x1,y1)到达另一点(x2,y2),因此(xi,yj)不能分别大于N或M.移动的限制是我们只能向右移动(1),向右下方(2)和向下移动(3),每次移动我们在括号中分配数字。鉴于这些运动,我们意识到我们不能向左或向上,所以x1必须小于x2且y1必须大于y2。 该算法将从第一个点(x1,y1)开始,并尝试创建三个“子”,每个运动一个: 对(x1 + 1) 对角线(x1 + 1,y1-1) 向下(y1-1) 要接受的每个孩子的条件是那些已经说过的条件,x1< = N,y1< = M,x1< = x2,y1> = y2。
迭代将尝试从每个被接受的孩子中再创建3个孩子(每个动作一个)。
这个迭代的结尾是每个孩子的(x1,y1)等于(x2,y2)。
提前致谢。
答案 0 :(得分:2)
迭代方法: 这可以通过memoization来解决,这意味着你可以跟踪no。在矩阵M中到达某个单元格的方法。
最初M[x][y] = 0 , for all x,y. b/w sx, dx and sy,dy respecitevly
<强>伪代码:强> 我们首先从源单元(sx,sy)开始,只有一种方法可以达到它,因此
sx,sy // source cell
dx,dy // destination cell
M[sx][sy] = 1 ;
for row x between sx, dx :
for column y between sx, dy:
if y-1 >= sy:
M[x][y] += M[x][y-1] // coming to x,y from left cell
if x-1 >= sx:
M[x][y] += M[x][y-1] // coming to x,y from top cell
if x-1 >= sx && y-1 >= sy:
M[x][y] += M[x-1][y-1] // coming from diagonal left cell.
答案是M [dx] [dy]。
递归方法: 采用与迭代方法相同的思想,也可以递归地实现:
Initially M[x][y] == -1: for all x b/w sx and dx , for all y b/w sy and dy
path( row, col )
if row == dx && col == dy:
return 1
if M[x][y] != -1: return M[x][y] // this means result for this is already calculated
M[x][y] = 0
if col+1 <= dy:
M[row][col] += path(row, col+1) // going right
if row+1 <= dx:
M[row][col] += path (row+1, col) // going down
if row+1 <= dx && col+1 <= dy:
M[row][col] += path(row+1, col+1) // going diagonally right
return M[row][col]
答案是M [sx] [sy]
答案 1 :(得分:0)
一个简单的递归解决方案是使用每个递归调用创建新的子代,例如
int foundSolutions = 0;
boolean pathExistsBetweenPoints(Point source, Point target, List<Point> previousPoints) {
//Check if we're there yet
if(source.x == target.x && source.y == target.y) {
foundSolutions++;
//Here you can display previousPoints if you want a possible solution
return true;
}
if(source.x > N || source.y > M || source.x > target.x || source.y > target.y) {
return false; //This trail is out of bounds
}
//Add this point to the list of points
List<Point> newPoints = previousPoints.add(source);
//Get the childpoints
Point rightPoint = new Point(source.x, source.y + 1);
Point diagonalPoint = new Point(source.x + 1, source.y + 1);
Point downPoint = new Point(source.x + 1, source.y);
//Check if any of the childs can reach the target
boolean validPath = pathExistsBetweenPoints(rightPoint, target, previousPoints);
validPath = validPath || pathExistsBetweenPoints(diagonalPoint, target, previousPoints);
validPath = validPath || pathExistsBetweenPoints(downPoint, target, previousPoints);
return validPath;
}
我不熟悉C ++语法,但这应该是可以翻译的