N皇后使用回溯

时间:2012-06-23 03:27:05

标签: c backtracking n-queens

我通过使用回溯实现了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;
}

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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;
}