回溯法之二---8皇后问题

回溯法之二---8皇后问题

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上.
问题分析:
第一步 定义问题的解空间
这个问题解空间就是8个皇后在棋盘中的位置.
第二步 定义解空间的结构
可以使用8*8的数组,但由于任意两个皇后都不能在同行,我们可以用数组下标表示
行,数组的值来表示皇后放的列,故可以简化为一个以维数组x[9]。
第三步 以深度优先的方式搜索解空间,并在搜索过程使用剪枝函数来剪枝
根据条件:x[i] == x[k]判断处于同一列
         abs(k-i) == abs(x[k]-x[i]判断是否处于同一斜线
我们很容易写出剪枝函数:
Cpp代码 复制代码
  1. bool canPlace(int k){   
  2.     for(int i = 1; i < k; i++){   
  3.         //判断处于同一列或同一斜线   
  4.        if(x[i] == x[k] || abs(k-i) == abs(x[k]-x[i]))              return false;   
  5.     }   
  6.     return true;   
  7. }  
bool canPlace(int k){
	for(int i = 1; i < k; i++){
        //判断处于同一列或同一斜线
	   if(x[i] == x[k] || abs(k-i) == abs(x[k]-x[i])) 		       return false;
	}
	return true;
}

然后我们按照回溯框架一,很容易写出8皇后的回溯代码:
Cpp代码 复制代码
  1. void queen(int i){   
  2.     if(i > 8){   
  3.         print();   
  4.         return;   
  5.     }   
  6.     for(int j = 1; j <= 8; j++){   
  7.       x[i] = j;//记录所放的列   
  8.       if(canPlace(i)) queen(i+1);   
  9.     }   
  10. }  
void queen(int i){
	if(i > 8){
		print();
		return;
	}
	for(int j = 1; j <= 8; j++){
	  x[i] = j;//记录所放的列
	  if(canPlace(i)) queen(i+1);
	}
}

整个代码:
Cpp代码 复制代码
  1. #include<iostream>   
  2. #include<cmath>   
  3. using namespace std;   
  4.   
  5. int x[9];   
  6. void print(){   
  7.     for(int i = 1; i <= 8; i++)   
  8.            cout << x[i] << " ";   
  9.     cout << endl;   
  10. }   
  11.   
  12. bool canPlace(int k){   
  13.     for(int i = 1; i < k; i++){   
  14.             //判断处于同一列或同一斜线   
  15.        if(x[i] == x[k] || abs(k-i) == abs(x[k]-x[i]))    
  16.            return false;   
  17.     }   
  18.     return true;   
  19. }   
  20.   
  21. void queen(int i){   
  22.     if(i > 8){   
  23.         print();   
  24.         return;   
  25.     }   
  26.     for(int j = 1; j <= 8; j++){   
  27.       x[i] = j;   
  28.       if(canPlace(i)) queen(i+1);   
  29.     }   
  30. }   
  31.   
  32. int main(){   
  33.   queen(1);   
  34.   return 0;   
  35. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值