您的位置:首页 > 其它

回溯法求解8皇后问题

2009-06-08 13:19 357 查看
//问题描述:在一个8×8国际象棋盘上,有8个皇后,每个皇后占一格;
//要求皇后间不会出现相互攻击的现象,即不能有两个皇后处在同一行、同一列或同一对角线上
//问共有多少种不同的摆放方法?

// 本解法采用回溯递归法,容易理解,
// 首先在棋盘上摆第一个皇后,然后摆第二个,每摆一个皇后则判断位置是否合法。
// 如果合法,则摆下一个皇后,如果不合法则在本行下一个位置尝试,所有位置尝试失败
// 则拿掉这个皇后,重新摆放上一个皇后的位置.
// 也就是说如果第n个皇后摆放失败 一直向上回溯 重新摆放第n-1皇后位置.
// 全局变量chess_board[]代表棋盘,每一行放一个皇后.
// 显然chess_board[4]==5 则说明第4个皇后放在第4行第5个位置
// 同理chess_board[1]==3 则说明第1个皇后放在第1行第3个位置
// 全局变量counter做计数器

 

#include <iostream>
#define MAX 8  
int chess_board[MAX+1];
int counter;
bool trial(int n)
{
 //本函数用于判定棋盘第N行的皇后位置是否合法    
 //并打印出合法的方案
 //为容易理解,本函数没有优化
 
 int left_diagonal = chess_board
- 1;
 int right_diagonal= chess_board
+ 1;
 for(int prior=n-1;prior>=1;prior--)
 {
  if(chess_board[prior] == chess_board
)         return false;
  //是否有同列的棋子
  if(chess_board[prior] == left_diagonal)          return false;
  //左斜线是否有棋子
  if(chess_board[prior] == right_diagonal)         return false;
  //右斜线是否有棋子
  left_diagonal --;
  right_diagonal ++;
 }
 
 //如果是最后一个棋子,并且摆放合法,则打印结果.
 if(n==MAX) 
 {
  counter++;
  std::cout<<"方法"<<counter<<":"<<"/t";
  for(int i=1;i<=MAX;i++) std::cout<<chess_board[i]<<" ";
  std::cout<<std::endl;
 }
 
 //摆放位置合法,返回true;
 return true;   
}

void search_position(int n)
{
 //本函数用于遍历棋盘第N行的皇后位置所有位置
 //每次都调用trial()来判定当前位置是否合法
 for(int position=1;position<=MAX;position++)
 {
  chess_board
= position;
  if(trial(n) && n<MAX)          search_position(n+1);
  //如果摆放位置合法,又不是最后一行,
  //则寻找下一行皇后的摆放位置
 }
}

int main(void)
{
 search_position(1);
 system("PAUSE");
 return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  search system 优化