1

我已经通过使用回溯实现了 N 个皇后问题的解决方案。我正在检查每个皇后的位置是否安全,方法是检查它的左上角、右上角和顶部,然后将其放在行中,否则我会回溯。

它为 N 的某些值(例如 4 和 8)提供了正确的解决方案,但对于其他值(例如 6)则不正确。

我不知道我错过了什么。任何帮助将不胜感激。

这是代码:

int S;
static int cnt=0;

int safepos(int board[][S+1],int i,int j)
{
    if(i==1)        
    return 1;

    int a,b;
    a=i-1;
    b=j-1;

    //checking for top-left side
    while(a>0 && b>0 )
    {
        if(board[a--][b--]==1)
        return 0;
    }

    a=i-1;
    b=j+1;
    //checking for top-right side    
    while(a>0 && b<=S )
    {
        if(board[a--][b++]==1)
        return 0;
    }

    //checking for the same column        
    for(a=1;a<i;a++)
        if(board[a][j]==1)
            return 0;
    return 1;
}

void Nqueens(int board[][S+1],int N,int n)  //n is the number of the rows
{
    if(n==N+1) //for those which reaches the last position we will have a solution
    {
        cnt++;
        return;    
    }
    int i;    
    for(i=1;i<=N;i++)  //for every column
    {
        if( safepos(board,n,i) )
        {
            board[n][i]=1;    
            Nqueens(board,N,n+1);  //checking for next row
        }
        board[n][i]=0;
    }
}

int main()
{
    int N=6;
    S=N;
    int board[N+1][N+1];    
    Nqueens(board,N,1);
    printf("%d",cnt);
    return 0;
}
4

2 回答 2

2

您对回溯想法的实现是正确的,问题在于必须手动将数组“板”的值初始化为零,默认情况下数组带有未定义的值。如果你这样做,你应该得到正确的答案,我测试了代码。有关数组初始化的更多信息,请参阅http://www.fredosaurus.com/notes-cpp/arrayptr/array-initialization.html

于 2012-06-27T02:08:17.200 回答
0

我知道这有一个公认的答案,但想分享我的实现,它使用初始化为 -1 而不是零的向量,以免干扰行 = 0 的零偏移

#include <iostream>
#include <vector>

const int GRID_SIZE = 8;


bool isValid ( int queenNum, int col, std::vector<int>& cols )
{
  // check for other queen number that collide with this one
  for ( int queenRow = 0; queenRow < queenNum; ++queenRow )
  {
    int queenCol = cols[queenRow];

    if ( col == queenCol )  
      return false; // same col

    if ((queenNum - queenRow) == abs( queenCol-col))
      return false; // same diagonal
  }
  return true;
}

void solve( int queenNum, std::vector<int>& cols,  std::vector<std::vector<int> >& results  )
{
  if ( queenNum == GRID_SIZE) 
  {
    // we have a solution 
    results.push_back (cols);
  }

  for ( int i = 0; i < GRID_SIZE; ++ i)
  {
    if ( isValid(queenNum,i,cols) )
    {
      cols[queenNum] = i;
      solve(queenNum + 1,cols, results);
    }
  }
}

void drawLine() {
  std::string line;
  for (int i=0;i<GRID_SIZE*2+1;i++)
    line.append("-");
  std::cout << line << std::endl;
}

void printBoard(std::vector<int>& cols) 
{
  drawLine();
  for(int i = 0; i < GRID_SIZE; i++){
    std::cout << "|";
    for (int j = 0; j < GRID_SIZE; j++){
      if (cols[i] == j) {
        std::cout << "Q|";
      } else {
        std::cout << " |";
      }
    }
    std::cout << std::endl;
    drawLine();
  }
  std::cout << "" << std::endl;;
}

void printBoards(std::vector<std::vector<int> >&  boards) {
  for (int i = 0; i < (int)boards.size(); i++) 
  {
    printBoard(boards[i]);
  }
}



int main ()
{
  std::vector<int> cols ( GRID_SIZE, -1);
  std::vector<std::vector<int> > results;
  solve(0, cols, results );
  printBoards(results);
  std::cout << results.size() << std::endl;
  return 0;
}
于 2013-10-25T23:38:20.137 回答