本博客(http://blog.csdn.net/livelylittlefish)贴出作者(三二一、小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正! 

                                     
                           

问题描述:

                                          
八皇后问题是大数学家高斯于1850年提出来的。该问题是在8×8的国际象棋棋盘上放置8个皇后,使得没有一个皇后能“吃掉”任何其他一个皇后,即没有任何两个皇后被放置在棋盘的同一行、同一列或同一斜线上。
                           

要求:

                             
编一个程序求出该问题的所有解。
                            

算法思想:

                            
回溯法
                            
使用回溯算法求解的问题特征,求解问题要分为若干步,且每一步都有几种可能的选择,而且往往在某个选择不成功时需要回头再试另外一种选择,如果到达求解目标则每一步的选择构成了问题的解,如果回头到第一步且没有新的选择则问题求解失败。
 
 
该问题也可扩展到N后问题求解,只需修改程序main函数中的n值即可。
                            

代码如下:

 
回溯算法 n后问题_回溯算法/************************************************************************
回溯算法 n后问题_n后问题_02 *  n后问题求解
回溯算法 n后问题_回溯算法_03 ***********************************************************************
*/

回溯算法 n后问题_回溯算法_04
回溯算法 n后问题_回溯算法_04#include 
<stdio.h>
回溯算法 n后问题_回溯算法_04#include 
<stdlib.h>
回溯算法 n后问题_回溯算法_04#include 
<math.h>
回溯算法 n后问题_回溯算法_04#include 
<conio.h>
回溯算法 n后问题_回溯算法_04
回溯算法 n后问题_回溯算法_04
#define MAXNUMBER 20
回溯算法 n后问题_回溯算法_04
回溯算法 n后问题_回溯算法_04
//判断当前得到的解向量是否满足问题的解
回溯算法 n后问题_回溯算法_04
bool place_queen(int x[],int k)
回溯算法 n后问题_n后问题_14
{
回溯算法 n后问题_n后问题_02    
int i;
回溯算法 n后问题_n后问题_02    
for(i=1;i<k;i++)
回溯算法 n后问题_n后问题_17    
{
回溯算法 n后问题_n后问题_02        
if((x[i]==x[k]) || (abs(x[i]-x[k])==abs(i-k)))
回溯算法 n后问题_n后问题_02            
return false;
回溯算法 n后问题_回溯算法_20    }

回溯算法 n后问题_n后问题_02
回溯算法 n后问题_n后问题_02    
return true;
回溯算法 n后问题_回溯算法_03}

回溯算法 n后问题_回溯算法_04
回溯算法 n后问题_回溯算法_04
//将结果简单信息打印到屏幕
回溯算法 n后问题_回溯算法_04
void output_queens(int x[],int n)
回溯算法 n后问题_回溯算法_27
{
回溯算法 n后问题_n后问题_02    
for(int i=1;i<=n;i++)
回溯算法 n后问题_n后问题_02        printf(
"%3d",x[i]);
回溯算法 n后问题_n后问题_02
回溯算法 n后问题_n后问题_02    printf(
" ");
回溯算法 n后问题_回溯算法_03}

回溯算法 n后问题_回溯算法_04
回溯算法 n后问题_回溯算法_04
//将结果详细信息写入文件
回溯算法 n后问题_回溯算法_04
void output_queens(FILE *fp,int number,int x[],int n)
回溯算法 n后问题_算法_36
{
回溯算法 n后问题_n后问题_02    fprintf(fp,
"solution %d: ",number);
回溯算法 n后问题_n后问题_02    
for(int i=1;i<=n;i++)
回溯算法 n后问题_n后问题_39    
{
回溯算法 n后问题_n后问题_02        
for(int j=1;j<=n;j++)
回溯算法 n后问题_算法_41        
{
回溯算法 n后问题_n后问题_02            
if(j==x[i])
回溯算法 n后问题_n后问题_02                fprintf(fp,
"1  ");
回溯算法 n后问题_n后问题_02            
else
回溯算法 n后问题_n后问题_02                fprintf(fp,
"0  ");
回溯算法 n后问题_回溯算法_20        }

回溯算法 n后问题_n后问题_02        fprintf(fp,
" ");
回溯算法 n后问题_回溯算法_20    }

回溯算法 n后问题_n后问题_02    fprintf(fp,
" ");
回溯算法 n后问题_回溯算法_03}

回溯算法 n后问题_回溯算法_04
回溯算法 n后问题_n后问题_52
/************************************************************************
回溯算法 n后问题_n后问题_02 *  n后问题求解
回溯算法 n后问题_n后问题_02 *  input  : n, the number of queens
回溯算法 n后问题_n后问题_02 *  output : the vector of solution, X
回溯算法 n后问题_回溯算法_03 ***********************************************************************
*/

回溯算法 n后问题_回溯算法_04
int n_queens(FILE *fp,int n,int x[])
回溯算法 n后问题_n后问题_58
{
回溯算法 n后问题_n后问题_02    
int nCount=0;    //解个数
回溯算法 n后问题_n后问题_02
    int k=1;        //先处理第1个皇后
回溯算法 n后问题_n后问题_02
    x[1]=0;
回溯算法 n后问题_n后问题_02
回溯算法 n后问题_n后问题_02    
while(k>0)
回溯算法 n后问题_n后问题_64    
{
回溯算法 n后问题_n后问题_02        x[k]
=x[k]+1;//在当前列加1的位置开始搜索
回溯算法 n后问题_n后问题_02

回溯算法 n后问题_n后问题_02        
while(x[k]<=&& !place_queen(x,k))    //当前列位置是否满足条件
回溯算法 n后问题_n后问题_02
            x[k]=x[k]+1;    //不满足,继续搜索下一列位置
回溯算法 n后问题_n后问题_02

回溯算法 n后问题_n后问题_02        
if(x[k]<=n)    //若存在满足条件的列
回溯算法 n后问题_算法_71
        {
回溯算法 n后问题_n后问题_02            
if(k==n)//是最后一个皇后,则得到一个最终解
回溯算法 n后问题_算法_73
            {
回溯算法 n后问题_n后问题_02                
//break;    //此处若break,则只能得到一个解
回溯算法 n后问题_n后问题_02
                nCount++;
回溯算法 n后问题_n后问题_02                output_queens(x,n);    
//输出
回溯算法 n后问题_n后问题_02
                output_queens(fp,nCount,x,n);
回溯算法 n后问题_回溯算法_20            }

回溯算法 n后问题_n后问题_02            
else    //否则,处理下一个皇后,即第 k+1 个皇后
回溯算法 n后问题_n后问题_80
            {
回溯算法 n后问题_n后问题_02                k
++;
回溯算法 n后问题_n后问题_02                x[k]
=0;
回溯算法 n后问题_回溯算法_20            }

回溯算法 n后问题_回溯算法_20        }

回溯算法 n后问题_n后问题_02        
else        //若不存在满足条件的列,则回溯
回溯算法 n后问题_算法_86
        {
回溯算法 n后问题_n后问题_02            x[k]
=0;    //第k个皇后复位为0
回溯算法 n后问题_n后问题_02
            k--;    //回溯到前一个皇后
回溯算法 n后问题_回溯算法_20
        }

回溯算法 n后问题_回溯算法_20    }

回溯算法 n后问题_n后问题_02
回溯算法 n后问题_n后问题_02    
return nCount;
回溯算法 n后问题_回溯算法_03}

回溯算法 n后问题_回溯算法_04
回溯算法 n后问题_回溯算法_04
int main()
回溯算法 n后问题_回溯算法_96
{
回溯算法 n后问题_n后问题_97    
int n=8,x[MAXNUMBER]={0};
回溯算法 n后问题_n后问题_02
回溯算法 n后问题_n后问题_02    FILE 
*fp=fopen("8皇后问题的解.txt","w");
回溯算法 n后问题_n后问题_02    
if(fp==NULL)
回溯算法 n后问题_n后问题_101    
{
回溯算法 n后问题_n后问题_02        printf(
"can not wirte file!");
回溯算法 n后问题_n后问题_02        exit(
0);
回溯算法 n后问题_回溯算法_20    }

回溯算法 n后问题_n后问题_02
回溯算法 n后问题_n后问题_02    printf(
"the queens are placed on the coloums : ");
回溯算法 n后问题_n后问题_02    
//求解并写入文件
回溯算法 n后问题_n后问题_02
    int nCount=n_queens(fp,n,x);
回溯算法 n后问题_n后问题_02    printf(
"there are %d solutions! ",nCount);
回溯算法 n后问题_n后问题_02    fclose(fp);
回溯算法 n后问题_n后问题_02    getch();    
回溯算法 n后问题_n后问题_02
回溯算法 n后问题_n后问题_02    
return 0;
回溯算法 n后问题_回溯算法_03}