递归面试题2 【八皇后】

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是19世纪著名的数学家高斯1850年提出:在8×8格的国际象棋盘上摆放8个皇后,使 其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。[英国某著名计算机图形图像公司面试题]

解析:递归实现n皇后问题。

算法分析:

数组a、b、c分别用来标记冲突,a数组代表列冲突,从a[0]~a[7]代表第0列到第7列。如果某列上已经有皇后,则为1,否则为0。

数组b代表主对角线冲突,为b[i-j+7],即从b[0]~b[14]。如果某条主对角线上已经有皇后,则为1,否则为0。

数组c代表从对角线冲突,为c[i+j],即从c[0]~c[14]。如果某条从对角线上已经有皇后,则为1,否则为0。

代码如下:

static
 
char
 Queen[
8
][
8
];

static
 
int
 a[
8
];

static
 
int
 b[
15
];

static
 
int
 c[
15
];

static
 
int
 iQueenNum
=
0

//
记录总的棋盘状态数




void
 qu(
int
 i); 
//
参数i代表行




int
 main()
{
  

int
 iLine,iColumn;

  
//
棋盘初始化,空格为*,放置皇后的地方为@


  
for
(iLine
=
0
;iLine
<
8
;iLine
++
)
  {
    a[iLine]

=
0

//
列标记初始化,表示无列冲突


    
for
(iColumn
=
0
;iColumn
<
8
;iColumn
++
)
      Queen[iLine][iColumn]

=

*

;
  }

  
//
主、从对角线标记初始化,表示没有冲突


  
for
(iLine
=
0
;iLine
<
15
;iLine
++
)
    b[iLine]

=
c[iLine]
=
0
;

  qu(
0
);
  

return
 
0
;
}


void
 qu(
int
 i)
{
  

int
 iColumn;

  
for
(iColumn
=
0
;iColumn
<
8
;iColumn
++
)
  {
    

if
(a[iColumn]
==
0
&&
b[i

iColumn
+
7
]
==
0
&&
c[i
+
iColumn]
==
0

    

//
如果无冲突


    {
      Queen[i][iColumn]

=

@

;
//
放皇后


      a[iColumn]
=
1

//
标记,下一次该列上不能放皇后


      b[i

iColumn
+
7
]
=
1

//
标记,下一次该主对角线上不能放皇后


      c[i
+
iColumn]
=
1

//
标记,下一次该从对角线上不能放皇后


      
if
(i
<
7
) qu(i
+
1
); 
//
如果行还没有遍历完,进入下一行


      
else
 
//
否则输出


      {
        

//
输出棋盘状态


        
int
 iLine,iColumn;
        printf(


第%d种状态为:\n

,
++
iQueenNum);
        

for
(iLine
=
0
;iLine
<
8
;iLine
++
)
        {
          

for
(iColumn
=
0
;iColumn
<
8
;iColumn
++
)
            printf(


%c 

,Queen[iLine][iColumn]);
          printf(


\n

);
        }
        printf(


\n\n

);
      }

      
//
如果前次的皇后放置导致后面的放置无论如何都不能满足要求,则回溯,重置


      Queen[i][iColumn]
=

*

;
      a[iColumn]

=
0
;
      b[i


iColumn
+
7
]
=
0
;
      c[i

+
iColumn]
=
0
;
    }
  }
}

 

    原文作者:八皇后问题
    原文地址: https://www.cnblogs.com/xfantasy/archive/2008/11/27/1342719.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞