八皇后

王朝百科·作者佚名  2010-01-11
窄屏简体版  字體: |||超大  

八皇后问题

递归算法八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。现代教学中,把八皇后问题当成一个经典递归算法例题。

算法分析:数组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;

另优化:第一个皇后在1~4格,最后*2,即为总解数

Pascal语言源程序program queens;

var a:array [1..8] of integer;

b,c,d:array [-7..16] of integer;

t,i,j,k:integer;

procedure print;

begin

t:=t+1;

write(t,': ');

for k:=1 to 8 do write(a[k],' ');

writeln;

end;

procedure try(i:integer);

var j:integer;

begin

if i>8 then print;{完成任务,打印结果}

for j:=1 to 8 do {每个皇后都有8种可能位置}

if (b[j]=0) and (c[i+j]=0) and (d[i-j]=0) then {判断位置是否冲突}

begin

a[i]:=j; {摆放皇后}

b[j]:=1; {宣布占领第J行}

c[i+j]:=1; {占领两个对角线}

d[i-j]:=1;

try(i+1); {8个皇后没有摆完,递归摆放下一皇后}

b[j]:=0; {回溯}

c[i+j]:=0;

d[i-j]:=0;

end;

end;

begin

fillchar(a,sizeof(a),0); {初始化数组}

fillchar(b,sizeof(b),0);

fillchar(c,sizeof(c),0);

fillchar(d,sizeof(d),0);

try(1);{从第1个皇后开始放置}

end.

C语言源程序#include "stdio.h"

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种状态为:

",++iQueenNum);

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

{

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

printf("%c ",Queen[iLine][iColumn]);

printf("

");

}

printf("

");

}

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

Queen[i][iColumn]='*';

a[iColumn]=0;

b[i-iColumn+7]=0;

c[i+iColumn]=0;

}

}

}

C++语言源程序#include <stdio.h>

#include <conio.h>

#include <math.h>

int n,k,a[20],num=0;

int attack(int k){

int flag=0;

int i=1;

while ((i<k)&&(a[k]!=a)&&(fabs(a[k]-a)!=(k-i))) i++;

if (i==k) flag=1;

return flag;

}

void place(int k)

{

//printf(" %d",k);

int i;

if (k==n+1){

num=num+1;

printf("num=%d:",num);

for (i=1;i<n+1;i++)

printf(" %d",a);

printf("

");}

else {

for (i=1;i<n+1;i++){

a[k]=i;

if (attack(k)==1) place(k+1);

else a[k]=0;

}

}

}

main(){

scanf("%d",&n);

k=1;

place(k);

if (k!=n+1) printf("no solution!

");

getch();

}

JAVA语言源程序public class testEghit {

private int[][] a=new int[8][8];

private int total=0;

public testEghit() {

init();

}

private void init(){

for(int i=0;i<8;i++){

for(int j=0;j<8;j++){

a[j]=0;

}

}

}

private void suma(){

int sum=0;

for(int i=0;i<8;i++){

for(int j=0;j<8;j++){

sum+=a[j];

}

}

if(sum>7){

total+=1;

System.out.println("sum="+sum);

for(int i=0;i<8;i++){

for(int j=0;j<8;j++){

System.out.print(a[j]+", ");

}

System.out.println("");

}

System.out.println("total="+total);

System.out.println("==============================");

}

// init();

}

private boolean check(int line,int col){

boolean o=false;

for(int i=0;i<8;i++){

if(a[line]==1) return o;

if(a[col]==1) return o;

if((line-i)>-1&&(col-i)>-1){

if(a[line-i][col-i]==1) return o;

}

if((line+i)<8&&(col+i)<8){

if(a[line+i][col+i]==1) return o;

}

if((line-i)>-1&&(col+i)<8){

if(a[line-i][col+i]==1) return o;

}

if((line+i)<8&&(col-i)>-1){

if(a[line+i][col-i]==1) return o;

}

}

return true;

}

private boolean com(int mazz){

boolean o=false;

for(int i=0;i<8;i++){

if(check(8-mazz,i)){

o=true;

a[8-mazz]=1;

if((mazz>1)&&!com(mazz-1)){

o=false;

a[8-mazz]=0;

}

if(mazz==1){

suma();

}

}

a[8-mazz]=0;

}

return o;

}

public static void main(String[] args) {

testEghit t=new testEghit();

t.com(8);

System.out.println("meiy");

}

}

C#语言源程序[font]using System;

using System.Collections.Generic;

using System.Text;

namespace EightQueen

{

class Program

{

class Eight

{

public int[] result = new int[8];

public static int amount = 0;

public void PrintResult()

{

Console.Write("Result: ");

foreach (int num in result)

{

Console.Write(num.ToString() + " ");

}

Console.WriteLine("

");

amount++;

}

}

static void PostQueen(ref Eight eig, int row)

{

if (row > 8 || row < 0)

{

return;

}

// the last pst is at row

// 3 Condition: not same row, not same column, not on the bias line

if (row < 7)

{

for (int i = row + 1; i < 8; i++)

{

int tint = eig.result[row] - eig.result;

if (0 == tint || tint == row - i || tint == i - row )

{

// should not be same column

return;

}

}

}

// if at the last Post

if (0 == row)

{

eig.PrintResult();

return;

}

// iterite to post next

for (int i = 0; i < 8; i++)

{

eig.result[row - 1] = i;

PostQueen(ref eig, row - 1);

}

}

static void Main(string[] args)

{

// Eight queen post on 8*8 grid

Eight eig = new Eight();

PostQueen(ref eig, 8);

Console.WriteLine(string.Format("The total arrange: {0}", Eight.amount));

Console.Read();

}

}

}

[/font]

[font class="Apple-style-span" style="font-style: italic;"]

[/font]

n皇后问题(英文)http://mathworld.wolfram.com/QueensProblem.html

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航