从原点到点的路径数

时间:2018-10-21 16:47:13

标签: java

我需要计算从原点到点(n,0)的路径数,其中n> 0,并且移动数必须恰好是2 * n。 我只能移动

(x + 1,y)[→],(x,y + 1)[↑],(x-1,y + 1)[-],(x + 1,y-1)[&] ,或(x +1,y +1)[%]。

限制是:

[-]和[&]从不以任何顺序直接相邻。

[↑]和[→]从不以任何顺序直接相邻。

[↑]和[%]从不以任何顺序直接相邻。

程序需要显示所有移动(x> 0和y> 0)。 示例:对于n = 7,(7)= 416449 我无法显示正确的答案。

    #include <iostream>
#include<regex>
using namespace std;

auto check = [](string &rp)->bool {
    regex reg("^(B)*(A)*");
    return regex_match(rp, reg);
};

int main()
{
    string rp;
    do{
       system("cls");
       cout<<"RP: ";
       getline(cin, rp);

    }while (!check(rp));

    cout<<"\n valid"<< rp<<endl;

    return 0;
}

}

2 个答案:

答案 0 :(得分:0)

private static boolean isPossibleOrigin(int x, int y, int n, int pasi) {
    return x >= 0 && y >= 0 && pasi < 2 * n && (x+y)/2<2*n-pasi;
}

public static int calcul(int x, int y, int n) {
    if (x == n && y == 0 ) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, 0)) {
        return
              right(x+1, y, n,1)
            + up(x, y+1, n, 1)
            + leftup(x-1, y+1, n, 1)
            + rightdown(x+1, y-1, n, 1)
            + rightup(x+1, y+1, n, 1);
    }
    return 0;
}
public static int right(int x, int y, int n, int pasi) {


    if (x == n && y == 0 && pasi == 2 * n) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, pasi)) {
        return
            right(x+1, y, n, pasi + 1)
                + leftup(x-1, y+1, n, pasi+1)
                + rightdown(x+1, y-1, n, pasi+1)
                + rightup(x+1, y+1, n,pasi+ 1);
    }
    return 0;
}
public static int leftup(int x, int y, int n, int pasi) {


    if (x == n && y == 0 && pasi == 2 * n) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, pasi)) {
        return
            right(x+1, y, n, pasi + 1)
                + leftup(x-1, y+1, n, pasi + 1)
                + up(x,y+1,n,pasi+1)
                + rightup(x+1, y+1, n,pasi+ 1);
    }
    return 0;
}
public static int rightup(int x, int y, int n, int pasi) {


    if (x == n && y == 0 && pasi == 2 * n) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, pasi)) {
        return
            right(x+1, y, n, pasi + 1)
            + leftup(x-1, y+1, n, pasi + 1)
                +rightdown(x+1, y-1, n, pasi+1)
                + rightup(x+1, y+1, n,pasi+ 1);
    }
    return 0;
}
public static int up(int x, int y, int n, int pasi) {


    if (x == n && y == 0 && pasi == 2 * n) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, pasi)) {
        return
            +up(x, y+1, n, pasi+1)
                + leftup(x-1, y+1, n, pasi + 1)
               +rightdown(x+1, y-1, n, pasi+1)
                ;
    }
    return 0;
}
public static int rightdown(int x, int y, int n, int pasi) {


    if (x == n && y == 0 && pasi == 2 * n) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, pasi)) {
        return
            right(x+1, y, n, pasi + 1)
           +rightdown(x+1, y-1, n, pasi+1)
                + up(x,y+1,n,pasi+1)
                + rightup(x+1, y+1, n, pasi + 1);
    }
    return 0;
}
public static void main(String[] args) {
System.out.println("Paths:"+calcul(0, 0, 1));
}

我认为是“?”可以替换为“(x + y)/ 2 <2 * n-pasi”对吗?

答案 1 :(得分:-1)

通常,此类问题可以通过纯递归来解决,而无需使用static变量。只需为每个可能的延续计数路径数。在给定的约束下到达期望的目的地后,将完整路径数增加1(return 1;),否则返回0来中断递归。

private static boolean isPossibleOrigin(int x, int y, int n, int pasi) {
    return x >= 0 && y >= 0 && pasi < 2 * n && ?;
}

public static int calcul(int x, int y, int n) {
    if (x == n && y == 0 && n == 0) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, 0)) {
        return
              right(x, y, n, 1)
            + up(x, y, n, 1)
            + leftup(x, y, n, 1)
            + rightdown(x, y, n, 1)
            + rightup(x, y, n, 1);
    }
    return 0;
}

为每个可能的方向写一个考虑其法律延续性的类似方法。

public static int right(int x, int y, int n, int pasi) {
    x = x+1;

    if (x == n && y == 0 && pasi == 2 * n) {
        return 1;
    } else if (isPossibleOrigin(x, y, n, pasi)) {
        return
            right(x, y, n, pasi + 1)
                + leftup(x, y, n, pasi + 1)
                + rightdown(x, y, n, pasi + 1)
                + rightup(x, y, n, pasi + 1);
    }
    return 0;
}

...

最后,您可以考虑到节点到目的地的距离大于剩余移动数时,访问节点将不会形成完整的路径,从而可以显着提高性能。我在现场留下了一个问号,这是一个添加适当条件进行检查的好地方。