算法快速回顾——八皇后问题

来源:互联网 发布:mac tex 编辑:程序博客网 时间:2024/06/05 07:03

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 


本文给出递归回溯解法,步骤如下:

1、通过在第n行第i列放置皇后

2、判断该位置是否合适。

3、如果合适则继续放置第n+1个皇后,不合适则选择第i+1列重新放置第n个皇后。

4、如果N个皇后都放置成功,则打印该结果。


具体实现如下:

TRIALSIZE是皇后个数。


#include "stdafx.h"#define TRIALSIZE 5#include<iostream>using namespace std;static int result_num = 0;void printData(int *data,int n){cout<<"result"<<result_num++<<": \n"<<endl;for(int i =0; i< n; i++){for(int j =0; j<n; j++)cout<<*(data+i*n+j)<<"\t";cout<<"\n"<<endl;}}//测试 row col 位置是否能放置 int TestData(int *data, int n, int row, int col){if(!data)return 0;for(int i =0; i< n; i++){//同行 if(*(data+i*n+col) == 1)return 0;for(int j =0; j<n; j++){//同列 if(*(data+(row)*n+j) == 1)return 0;//同对角线 if(((i-row)==(j-col)||(i-row)==(col -j))&&(*(data+i*n+j)==1))return 0;}}return 1;}//假设data为n*n的棋盘,需要放置n个棋子。前i-1个棋子已经放置好,且符合约束条件:任意两个棋子不同行、不同列、不同对角线。//i (1...n) j (1...n) 如果有棋子 该位置为1void Trial(int *data, int i, int n){if(i > n )printData(data,n);else{for(int j = 1; j <= n; ++j){if(TestData(data,n,i-1,j-1)){*(data+(i-1)*n+j-1) = 1;Trial(data,i+1,n);*(data+(i-1)*n+j-1) = 0;}}}}//测试int main(int argc, char* argv[]){int *data = new int[TRIALSIZE*TRIALSIZE];memset(data,0,sizeof(int)*TRIALSIZE*TRIALSIZE);Trial(data,1,TRIALSIZE);}



0 0