boolean[] diagonal = new boolean[16]; // 对角线安全标志
目前创新互联建站已为1000+的企业提供了网站建设、域名、雅安服务器托管、网站托管、服务器托管、企业网站设计、猇亭网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
boolean[] undiagonal = new boolean[16]; // 反对角线安全标志
用上两个判断是否能放置棋子
在 n 行 n 列的国际象棋棋盘上,最多可布n个皇后。
若两个皇后位于同一行、同一列、同一对角线上,
则称为它们为互相攻击。
n皇后问题是指找到这 n 个皇后的互不攻击的布局。
n 行 n 列的棋盘上,主次对角线各有2n-1条。
利用行号i和列号j计算
主对角线编号k的方法是k = n+i-j-1;
计算次对角线编号k的方法是k = i+j
你主要是算法有些模糊罢了,现在我怕我说的不好将你弄的越来越混乱所以给你个叫形象的若是还不明白,call me
package 百度;
//演示程序:n个皇后问题
import java.io.*;
/*
在 n 行 n 列的国际象棋棋盘上,最多可布n个皇后。
若两个皇后位于同一行、同一列、同一对角线上,
则称为它们为互相攻击。
n皇后问题是指找到这 n 个皇后的互不攻击的布局。
n 行 n 列的棋盘上,主次对角线各有2n-1条。
利用行号i和列号j计算
主对角线编号k的方法是k = n+i-j-1;
计算次对角线编号k的方法是k = i+j
*/
//"n个皇后问题"之类定义
public class cQueen {
int n; //皇后问题的大小
int col[]; //数组,各列上有无皇后(0,1)
int md[]; //数组,各主对角线有无皇后(0,1)
int sd[]; //数组,各次对角线有无皇后(0,1)
int q[]; //数组,第i行上皇后在第几列(0,n-1)
int Q; //已布皇后数,计数
int r; //n皇后问题的解的组数
//构造函数 n皇后问题的初始化
public cQueen(int m) {
n=m;Q=0;r=0;
col=new int[n];
md=new int[2*n-1]; //初始化0
sd=new int[2*n-1];
q=new int[n];
}
//函数:打印棋盘
public void showBoard() {
int i,j;
for(i=0;in;i++) {
for(j=0;jn;j++)
if(q[i]==j) System.out.print("1 ");
else System.out.print("0 ");
System.out.println();
}
r++; //解的组数
System.out.println("---------------");
}
//求解n皇后问题
/*
此函数试图在n*n的棋盘的第i行上放一个皇后,
若找到可以放的位置,就递归调用自身试图在i+1行
放另一个皇后,若第i行是最后一行,则打印棋盘。
*/
public void resolve(int i) {
int j;
// 在第i行给定后检查棋盘上的每一列
for(j=0;jn;j++) {
//如果在第i行的第j列可以布放皇后
if(col[j]==0md[n+i-j-1]==0sd[i+j]==0){
Q++;q[i]=j; //布放皇后,第i行皇后在第几列
// 标记新布皇后的攻击范围
col[j]=md[n+i-j-1]=sd[i+j]=1;
// 如果已经布了n个皇后(得到了一组解),
// 把棋盘(解)打印出来。
if(Q==n) showBoard();
// 否则,递归。在第i行第j列布放皇后的前提下,
//试探下一行(i+1行)在哪一列布皇后?
else if(in-1) resolve(i+1);
else resolve(0); //因为约定起始行可以任选
//移除在第i行的第j列新布的皇后,
//并消除所标记的攻击范围,为回溯作准备。
Q--; q[i]=0;
col[j]=md[n+i-j-1]=sd[i+j]=0;
//试探在第i行的第j+1列新布皇后的方案(新解)
}
} //下一列,j循环
//对于给定的行,列扫描完毕后,从这里回溯。
}
//输出解的个数
public void HowMany() {
System.out.println(n+"皇后问题共有解"+r+"组。");
}
//主方法main()
public static void main(String []args) {
//定义一个8皇后问题(有92组解)
cQueen Q1=new cQueen(8); //大于10,你的微机可能要死机!
//第一个皇后可以在任意一行布放
Q1.resolve(0); //参数在0到n-1之间任选
Q1.HowMany();
}
} //类Queen定义结束
关于看代码的人人都知道的小技巧,最小试探法来输出结果进行比较和分析
你main方法也没有加上,这样吧,我给你看代码,这个比较容易理解。
package com.aice.queen;
public class Queen{
//同栏是否有皇后,1表示有
private int[]column;
//右上至左下是否有皇后
private int[]rup;
//左上至右下是否有皇后
private int[]lup;
//解答
private int[]queen;
//解答编号
private int num;
public Queen(){
column = new int[8+1];
rup =new int[(2*8)+1];
lup = new int[(2*8)+1];
for(int i = 1;i=8;i++)
column[i]=1;
for(int i = 1;i=(2*8);i++)
rup[i] = lup[i] = 1;
queen = new int[8+1];
}
public void backtrack(int i){
if(i8){
showAnswer();
}else{
for(int j=1;j=8;j++){
if((column[j]==1)(rup[i+j]==1)
(lup[i-j+8]==1)){
queen[i]=j;
//设定为占用
column[j]=rup[i+j]=lup[i-j+8]=0;
backtrack(i+1);
column[j]=rup[i+j]=lup[i-j+8]=1;
}
}
}
}
protected void showAnswer(){
num++;
System.out.println("\n解答"+num);
for(int y=1;y=8;y++){
for(int x=1;x=8;x++){
if(queen[y]==x){
System.out.print("Q");
}else{
System.out.print(".");
}
}
System.out.println();
}
}
public static void main(String[]args){
Queen queen = new Queen();
queen.backtrack(1);
}
}
public class Queen{//同栏是否有皇后,1表示有private int[] column;//右上至左下是否有皇后private int[] rup;//左上至右下是否有皇后private int[] lup;//解答private int[] queen;//解答编号private int num;public Queen(){column=new int[8+1];rup=new int[(2*8)+1];lup=new int[(2*8)+1];for(int i=1;i=8;i++)column[i]=0;for(int i=1;i=(2*8);i++)rup[i]=lup[i]=0; //初始定义全部无皇后 queen=new int[8+1];} public void backtrack(int i){if(i8){showAnswer();}else{for(int j=1;j=8;j++){if((column[j]==0)(rup[i+j]==0)(lup[i-j+8]==0)){//若无皇后queen[i]=j;//设定为占用column[j]=rup[i+j]=lup[i-j+8]=1;backtrack(i+1); //循环调用column[j]=rup[i+j]=lup[i-j+8]=0;}}}} protected void showAnswer(){num++;System.out.println("\n解答"+num); for(int y=1;y=8;y++){for(int x=1;x=8;x++){if(queen[y]==x){System.out.print("Q");}else{System.out.print(".");}} System.out.println();}} public static void main(String[]args){Queen queen=new Queen();queen.backtrack(1);}}
[cpp] view plaincopyprint?
//--------------------------------------
//利用函数递归,解决八皇后问题
//
// zssure 2014-03-12
//--------------------------------------
#include stdio.h
#include cmath
int count=0;//全局计数变量
/*--------------------四个皇后----------------------*/
//#define QUEEN_NUM 4
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,
// 0,0,0,0,
// 0,0,0,0,
// 0,0,0,0 };
/*--------------------五个皇后----------------------*/
//#define QUEEN_NUM 5
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0,
// 0,0,0,0,0 };
/*--------------------六个皇后----------------------*/
//#define QUEEN_NUM 6
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0,
// 0,0,0,0,0,0
// };
/*--------------------七个皇后----------------------*/
//#define QUEEN_NUM 7
//int label[QUEEN_NUM][QUEEN_NUM]={ 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0,
// 0,0,0,0,0,0,0
// };
/*--------------------八个皇后----------------------*/
#define QUEEN_NUM 8
int label[QUEEN_NUM][QUEEN_NUM]={0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0};
void FillChessbox(int m,int n,int num)
{
for(int i=0;iQUEEN_NUM;++i)
for(int j=0;jQUEEN_NUM;++j)
if(abs(i-m)==abs(j-n))//对角区域填充
{
if(label[i][j]==0)
label[i][j]=num;
}
int i=0,j=0;
while(iQUEEN_NUM)//行填充
{
if(label[i][n]==0)
label[i][n]=num;
++i;
}
while(jQUEEN_NUM)//列填充
{
if(label[m][j]==0)
label[m][j]=num;
++j;
}
}
void ClearChessBox(int m,int n,int num)
{
for(int i=0;iQUEEN_NUM;++i)
for(int j=0;jQUEEN_NUM;++j)
if(abs(i-m)==abs(j-n) label[i][j]==num)
label[i][j]=0;
int i=0,j=0;
while(iQUEEN_NUM)
{
if(label[i][n]==num)
label[i][n]=0;
++i;
}
while(jQUEEN_NUM)
{
if(label[m][j]==num)
label[m][j]=0;
++j;
}
}
void AllClear()
{
for(int i=0;iQUEEN_NUM;++i)
for(int j=0;jQUEEN_NUM;++j)
label[i][j]=0;
}
void PrintResult()
{
for(int i=0;iQUEEN_NUM;++i)
{
for(int j=0;jQUEEN_NUM;++j)
printf("%d ",label[i][j]);
printf("\n");
}
}
bool EightQueen(int n/*皇后个数*/,int c/*已经放置的皇后个数*/)
{
//static int count=0;
//小于3x3的棋盘是无解的
if(n4)
return false;
for(int i=0;in;++i)
{
if(label[c-1][i]==0)//存在可以放置第c个皇后的位置
{
label[c-1][i]=c+1;
if(c==n)/*已经放置完毕所有的皇后*/
{
++count;
PrintResult();
printf("**************************\n");
ClearChessBox(c-1,i,c+1);
//AllClear();
return true;
}
FillChessbox(c-1,i,c+1);
EightQueen(n,c+1);
ClearChessBox(c-1,i,c+1);
/*-------------------------------------------------------------------------------------------------------------------------
// 现场恢复,无论下一个皇后是否顺利放置,都应该恢复现场。原因是
//
// 如果下一个皇后放置失败,那么自然应该将本次放置的皇后去除,重新放置,所以需要进行现场恢复(即回溯);
// 如果下一个皇后放置成功,意味着本次放置已经满足条件,是一个解,此时需要恢复现场,进行下一次的重新放置,寻找下一个解。
//
//------------------------------------------------------------------------------------------------------------------------*/
//if(!EightQueen(n,c+1))
// ClearChessBox(c-1,i,c+1);
}
}
return false;
}
int main()
{
EightQueen(QUEEN_NUM,1);
printf("%d\n",count);
return 0;
}