C++ N-Rooks解决方案数回溯

C++ N-Rooks解决方案数回溯,c++,algorithm,backtracking,C++,Algorithm,Backtracking,这些方法应该给出任意数量的车在非攻击性排列中可能在一块板上的排列计数。 我知道我一定错过了一些愚蠢的事情。帮帮我。由于某些原因,我返回的解决方案计数为off,即使在打印语句中找到了6个解决方案。。。我已尝试打印阵列,在找到解决方案时打印。。。我找不到任何有用的东西 编辑*:用户界面不完整。忽略其中的错误。我更关心findnumsolution()方法得到的错误结果。我尝试过直接通过构造函数传递值,但它仍然给我错误的答案。3x3板,带3块,返回5块,4x4板,带4块返回13块 编辑**:清除不相关

这些方法应该给出任意数量的车在非攻击性排列中可能在一块板上的排列计数。 我知道我一定错过了一些愚蠢的事情。帮帮我。由于某些原因,我返回的解决方案计数为off,即使在打印语句中找到了6个解决方案。。。我已尝试打印阵列,在找到解决方案时打印。。。我找不到任何有用的东西

编辑*:用户界面不完整。忽略其中的错误。我更关心findnumsolution()方法得到的错误结果。我尝试过直接通过构造函数传递值,但它仍然给我错误的答案。3x3板,带3块,返回5块,4x4板,带4块返回13块

编辑**:清除不相关的代码

NRooks(int board[8][8], int n, int k)
{
    numRooks = n;
    boardSize = k;
    numSolutions = 0;
    for(int i = 0; i < 8; i++)
        for(int j = 0; j < 8; j++)
            board[i][j] = 0;
    numSolutions = findNumSolutions(board, 0, numRooks);
}

bool canPlace(int col, int row, int board[8][8])
{
    for(int i = col-1; i >= 0; i--){
        if(board[i][row] == 1){
            return false;
        }
    }
    return true;
}

int findNumSolutions(int board[8][8], int col, int rooksLeft)
{
   if(col > boardSize||rooksLeft ==0)
       return 1;
   int nsolutions = 0;
   for(int i = 0; i < boardSize; i++){
        board[col][i] = 1;
        if(!canPlace(col, i, board)){
            continue;
        }
        nsolutions += findNumSolutions(board, col + 1, rooksLeft - 1);
        board[col][i] = 0;
    }
    return nsolutions;
}
NRooks(int board[8][8],int n,int k)
{
numRooks=n;
boardSize=k;
numSolutions=0;
对于(int i=0;i<8;i++)
对于(int j=0;j<8;j++)
板[i][j]=0;
numSolutions=findNumSolutions(单板,0,numRooks);
}
布尔canPlace(整数列、整数行、整数板[8][8])
{
对于(int i=col-1;i>=0;i--){
如果(板[i][row]==1){
返回false;
}
}
返回true;
}
int findNumSolutions(int board[8][8],int col,int rooksleet)
{
如果(col>boardSize | | rooksleet==0)
返回1;
int-nsolutions=0;
对于(int i=0;i
第一个错误现已修复,即在递归函数中使用成员变量,而在递归函数中应使用局部变量。这里有两种变体:要么返回每次调用的号码,要么使用全局函数或成员函数并在其中累积解决方案。不要混用这些方法

第二个错误,在原始帖子中没有,但在发布整个代码时引入,如下所示:

// try placing piece in row of col
for(int i = 0; i < boardSize; i++){
    board[col][i] = 1;
    if(!canPlace(col, i, board)){
        continue;
    }
    nsolutions += findNumSolutions(board, col + 1, rooksLeft - 1);
    board[col][i] = 0;
}

第一个错误(现已修复)是在递归函数中使用成员变量,其中应使用局部变量。这里有两种变体:要么返回每次调用的号码,要么使用全局函数或成员函数并在其中累积解决方案。不要混用这些方法

第二个错误,在原始帖子中没有,但在发布整个代码时引入,如下所示:

// try placing piece in row of col
for(int i = 0; i < boardSize; i++){
    board[col][i] = 1;
    if(!canPlace(col, i, board)){
        continue;
    }
    nsolutions += findNumSolutions(board, col + 1, rooksLeft - 1);
    board[col][i] = 0;
}

我不教这个代码的错误,但我有更有效的解决方案,没有回溯。这只是一道数学题

这个问题是:给定整数N和K,找出将N个rook放入K*K板的方法数。

如果N>K,则答案为零。
如果N=K,答案是K!。因为您可以在每列中选择一个rook,所以方法的数量等于
p={1,2,3,…,K}


让我们考虑N 实际上,答案是
P(K,N)*C(K,N)

如果电路板大小为N*K,您只能选择满足1的排列我不教这段代码的错误,但我有更有效的解决方案,无需回溯。这只是一道数学题

这个问题是:给定整数N和K,找出将N个rook放入K*K板的方法数。

如果N>K,则答案为零。
如果N=K,答案是K!。因为您可以在每列中选择一个rook,所以方法的数量等于
p={1,2,3,…,K}


让我们考虑N 实际上,答案是
P(K,N)*C(K,N)

如果电路板大小为N*K,您只能选择满足1I的排列,使用square1001描述的方法

#include <iostream>
using namespace std;

long long fact(int n)
{
    long long factorial=1;
    if(n<=0)
    {
        return 1;
    }
    for(int i=1; i<=n; ++i)
    {
        factorial *= i;              // factorial = factorial*i;
    }
    return factorial;
}
long long permutation(int n, int r) {
    if( n<=0 || r<= 0)
    {
        return 1;
    }
    return fact(n)/fact(n-r);
}

long long combination(int n, int r) {
    if(r > n / 2) r = n - r; // because C(n, r) == C(n, n - r)
    long long ans = 1;
    int i;

    for(i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    }

    return ans;
}

long long findNumSolutions(int boardSize,int numberofRooks)
{
    if(numberofRooks>boardSize || numberofRooks <=0)
    {
        return 0;
    }
    long long comb=combination(boardSize,numberofRooks);
    long long  perm=permutation(boardSize,numberofRooks);
    cout<<"comb : "<<comb<<endl;
    cout<<"perm : "<<perm<<endl;
    return comb*perm;
}

int main ()
{
  std::cout <<findNumSolutions(3,3)<<endl;

  return 0;
}
#包括
使用名称空间std;
长事实(int n)
{
长阶乘=1;

如果(n我正在使用square1001描述的方法

#include <iostream>
using namespace std;

long long fact(int n)
{
    long long factorial=1;
    if(n<=0)
    {
        return 1;
    }
    for(int i=1; i<=n; ++i)
    {
        factorial *= i;              // factorial = factorial*i;
    }
    return factorial;
}
long long permutation(int n, int r) {
    if( n<=0 || r<= 0)
    {
        return 1;
    }
    return fact(n)/fact(n-r);
}

long long combination(int n, int r) {
    if(r > n / 2) r = n - r; // because C(n, r) == C(n, n - r)
    long long ans = 1;
    int i;

    for(i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    }

    return ans;
}

long long findNumSolutions(int boardSize,int numberofRooks)
{
    if(numberofRooks>boardSize || numberofRooks <=0)
    {
        return 0;
    }
    long long comb=combination(boardSize,numberofRooks);
    long long  perm=permutation(boardSize,numberofRooks);
    cout<<"comb : "<<comb<<endl;
    cout<<"perm : "<<perm<<endl;
    return comb*perm;
}

int main ()
{
  std::cout <<findNumSolutions(3,3)<<endl;

  return 0;
}
#包括
使用名称空间std;
长事实(int n)
{
长阶乘=1;

如果(nIs
numSolutions
是全局变量或'NRooks
的成员,请将其设置为本地变量,因为每次调用
findNumSolutions`都需要自己的副本。这是我遗漏的一点。仍然是“0”尽管如此。是的,我知道我应该得到什么,我只是想知道为什么这不起作用,只是更改成员变量的修改。
numSolutions=0;
,在
NRooks::findNumSolutions
中,对局部变量的声明:
int numSolutions=0;
。(并删除同名的成员变量;您不需要它。)它现在应该可以工作了。事实上,它确实改变了一些事情,但由于某种原因,结果仍然是错的。3x3板3块,我得到了5个解决方案,4x4板4块,我得到了13个。我不知道。我使用了你发布的原始代码,重新保存了这个类,并添加了一些你没有显示的东西,使它工作,它给了我很好的结果。你从b开始吗这都是零?也许你应该共享整个程序;可能还有其他错误。
numSolutions
是全局变量还是'NRooks
的成员?将其设置为局部变量,因为每次调用
findNumSolutions`都需要自己的副本。这是我遗漏的一点。仍然是“0”尽管如此。是的,我知道我应该得到什么,我只是想知道为什么这不起作用,只是更改成员变量的修改。
numSolutions=0;
,在
NRooks::findNumSolutions
中,对局部变量的声明:
int numSolutions=0;
。(并删除同名的成员变量;您不需要它。)它现在应该可以工作了。事实上,它确实改变了一些事情,但由于某种原因,结果仍然是无效的。3x3板3块,我得到5个解决方案,4x4板4块,我得到13个。我不知道。我使用了您发布的原始代码,重新保存了类并添加了一些stuf
#include <iostream>
using namespace std;

long long fact(int n)
{
    long long factorial=1;
    if(n<=0)
    {
        return 1;
    }
    for(int i=1; i<=n; ++i)
    {
        factorial *= i;              // factorial = factorial*i;
    }
    return factorial;
}
long long permutation(int n, int r) {
    if( n<=0 || r<= 0)
    {
        return 1;
    }
    return fact(n)/fact(n-r);
}

long long combination(int n, int r) {
    if(r > n / 2) r = n - r; // because C(n, r) == C(n, n - r)
    long long ans = 1;
    int i;

    for(i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    }

    return ans;
}

long long findNumSolutions(int boardSize,int numberofRooks)
{
    if(numberofRooks>boardSize || numberofRooks <=0)
    {
        return 0;
    }
    long long comb=combination(boardSize,numberofRooks);
    long long  perm=permutation(boardSize,numberofRooks);
    cout<<"comb : "<<comb<<endl;
    cout<<"perm : "<<perm<<endl;
    return comb*perm;
}

int main ()
{
  std::cout <<findNumSolutions(3,3)<<endl;

  return 0;
}