A. 八皇后C++算法流程图
国际象棋还是扑克?
B. 八皇后问题的算法思想实现起来可不可以简单些
#include <stdio.h>
#include <math.h>
#define N 8
void Check(int p[]){
int i,j;
for(i=0;i<N;i++)
for(j=i+1;j<N;j++)
if(abs(p[j]-p[i])==j-i)
return;
for(i=0;i<N;i++)
printf("%d ",p[i]);
printf("\n");
}
void Permute(int n,int p[]){
int i,j;
if(n==1)
Check(p);
for(i=0,j=n-1;i<N;i++)
if(!p[i]){
p[i]=j; Permute(j,p); p[i]=0;
}
}
int main(){
static int p[N];
int n=N;
Permute(n+1,p);
return 0;
}
C. 八皇后问题递归算法不理解,求解
layout[row] = i; //尝试在此位置上放上八皇后
放上去之后才开始检查是不是合符八皇后的规则,
if(isSafe(row, i)) // 结果为true 意思是在此位置上放八皇后是符合规则的
lay(row+1) //那么OK,我们可以继续放下一层
八皇后是典型的循环里面加递归, 和全排列很类似。在之后你可以看看DFS,深搜就是用这个原理
D. 八皇后问题求解的实现算法
#include <stdio.h>
#include <math.h>
#define N 8
void Check(int p[]){
int i,j;
for(i=0;i<N;i++)
for(j=i+1;j<N;j++)
if(abs(p[j]-p[i])==j-i)
return;
for(i=0;i<N;i++)
printf("%d ",p[i]);
printf("\n");
}
void Permute(int n,int p[]){
int i,j;
if(n==1)
Check(p);
for(i=0,j=n-1;i<N;i++)
if(!p[i]){
p[i]=j; Permute(j,p); p[i]=0;
}
}
int main(){
static int p[N];
int n=N;
Permute(n+1,p);
return 0;
}
E. 用递归函数设计八皇后问题的回溯算法C++代码
解析:递归实现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。
代码如下:
#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种状态为:\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;
}
}
}
F. JAVA中八皇后问题算法和流程图。要求用回溯法,求大神解答,在线等如果有代码就完美了
[cpp] view plainprint?
//--------------------------------------
//利用函数递归,解决八皇后问题
//
// 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;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n))//对角区域填充
{
if(label[i][j]==0)
label[i][j]=num;
}
int i=0,j=0;
while(i<QUEEN_NUM)//行填充
{
if(label[i][n]==0)
label[i][n]=num;
++i;
}
while(j<QUEEN_NUM)//列填充
{
if(label[m][j]==0)
label[m][j]=num;
++j;
}
}
void ClearChessBox(int m,int n,int num)
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
if(abs(i-m)==abs(j-n) && label[i][j]==num)
label[i][j]=0;
int i=0,j=0;
while(i<QUEEN_NUM)
{
if(label[i][n]==num)
label[i][n]=0;
++i;
}
while(j<QUEEN_NUM)
{
if(label[m][j]==num)
label[m][j]=0;
++j;
}
}
void AllClear()
{
for(int i=0;i<QUEEN_NUM;++i)
for(int j=0;j<QUEEN_NUM;++j)
label[i][j]=0;
}
void PrintResult()
{
for(int i=0;i<QUEEN_NUM;++i)
{
for(int j=0;j<QUEEN_NUM;++j)
printf("%d ",label[i][j]);
printf("\n");
}
}
bool EightQueen(int n/*皇后个数*/,int c/*已经放置的皇后个数*/)
{
//static int count=0;
//小于3x3的棋盘是无解的
if(n<4)
return false;
for(int i=0;i<n;++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;
}
G. 寻求八皇后的迭代算法解释。
也不知是不是你想要的解释,采用回溯法:(以前写的,直接粘贴……)
用一个函数来判断某个位置是否安全,安全的位置说明它所在的行、列和对角线上都没有放置皇后,因此不会出现皇后互相攻击的情况;否则该位置不安全。其具体实现的过程是找出所有放置过的皇后,将它们的位置与该位置进行比较判断。又注意到同一行最多只能放置一个皇后,因此,只需要对前面的各行逐行扫描皇后,就可以找出所有皇后的位置。
为便于显示,假设棋盘的状态为“-”时表示未放皇后状态,为“Q”时表示放置了皇后的状态。
//
判断位置(
row,
col
)是否是安全位置
bool
safeJudge(
int
row,
int
col
)
const
{
int
qRow,
qCol;
//
检查前面各行,看与前面放置的皇后是否发生攻击
for(
qRow
=
0;
qRow
<
row;
qRow++
)
{
string
rowState
=
chessState[
qRow
];
//
寻找第qRow行放置皇后的列数
qCol
=
rowState.find(
"Q"
);
//
判断是否安全
if(
qRow
==
row
||
qCol
==
col
||
(
qCol
-
qRow
)
==
(
col
-
row
)
||
(
qCol
+
qRow
)
==
(
col
+
row
)
)
return
false;
}
return
true;
}
试着先把第一个皇后放在棋盘上,然后再放第二个皇后,使两个皇后不会互相攻击,再放第三个皇后,使得它与前两个皇后都不会互相攻击,以此类推,直至所有的皇后都放上去。如果第七个皇后放上后,第八个皇后已经没有安全位置可以放置,则试着调整第七个皇后的位置,再尝试第八个皇后有没有安全位置;如果第七个皇后的所有安全位置都已尝试过了,第八个皇后还是没有安全位置,则试着调整第六个皇后的位置。如此类推,最糟糕的情况是一直到将第一个皇后的位置进行调整。由此可见,采用回溯法,过程的实现形式非常简单自然,然而这一过程的工作量非常大。
void
QueenChess::placeQueen(
int
row
)
{
//
穷尽第row行的所有列
for(
int
col
=
0;
col
<
8;
col++
)
{
if(
safeJudge(
row,
col
)
)
{
chessState[
row
][
col
]
=
"Q";
//
若还没有放到第八行,则尝试下一行
if(
row
<
7
)
placeQueen(
row
+
1
);
//
已经放置了八个皇后,打印出成功的棋盘,并将解数加1
else
{
solves++;
drawChess();
}
}
//
将该处的皇后取走,尝试下一列位置
chessState[
row
]
=
"--------";
}
}
这个算法能发现所有可能的解,不过它认为棋盘是具有行列编号的。事实上,棋盘并没有行列编号,如位置(0,0)和(7,7)其实是对称位置,因此这种算法给出的某些解也是对称的。为了便于理解,假设棋盘是具有行列编号的。
建立一个QueenChess类,见相应程序。
QueenChess::QueenChess()
{
solves
=
0;
for(
int
i
=
0;
i
<
8;
i++
)
chessState[
i
]
=
"--------";
}
void
QueenChess::drawChess()
{
int
i,
j;
cout
<<
"\n八皇后问题的第"
<<
solves
<<
"个解为:"
<<
endl;
cout
<<
"
0
1
2
3
4
5
6
7"
<<
endl;
for(
i
=
0;
i
<
8;
i++
)
{
cout
<<
i
<<
"
";
for(
j
=
0;
j
<
8;
j++
)
cout
<<
chessState[
i
][
j
]
<<
"
";
cout
<<
endl;
}
system(
"pause"
);
}
void
QueenChess::solve()
{
//
从第0行开始放置皇后
placeQueen(
0
);
cout
<<
"\n八皇后问题总共的解的个数为:"
<<
solves
<<
endl;
}
H. 八皇后算法 free pascal
〖问题描述〗
在一个8×8的棋盘里放置8个皇后,要求每个皇后两两之间不相"冲"(在每一横列竖列斜列只有一个皇后)。
〖问题分析〗(聿怀中学吕思博)
这道题可以用递归循环来做,分别一一测试每一种摆法,直到得出正确的答案。主要解决以下几个问题:
1、冲突。包括行、列、两条对角线:
(1)列:规定每一列放一个皇后,不会造成列上的冲突;
(2)行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;
(3)对角线:对角线有两个方向。在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。
2、数据结构。
(1)解数组A。A[I]表示第I个皇后放置的列;范围:1..8
(2)行冲突标记数组B。B[I]=0表示第I行空闲;B[I]=1表示第I行被占领;范围:1..8
(3)对角线冲突标记数组C、D。
C[I-J]=0表示第(I-J)条对角线空闲;C[I-J]=1表示第(I-J)条对角线被占领;范围:-7..7
D[I+J]=0表示第(I+J)条对角线空闲;D[I+J]=1表示第(I+J)条对角线被占领;范围:2..16
〖算法流程〗
1、数据初始化。
2、从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领):
如果是,摆放第n个皇后,并宣布占领(记得要横列竖列斜列一起来哦),接着进行递归;
如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,却发现此时已经无法摆放时,便要进行回溯。
3、当n>;8时,便一一打印出结果。
〖优点〗逐一测试标准答案,不会有漏网之鱼。
〖参考程序〗queen.pas
----------------------------------------------------------------------------
programtt;
vara:array[1..8]ofinteger;
b,c,d:array[-7..16]ofinteger;
t,i,j,k:integer;
procereprint;
begin
t:=t+1;
write(t,'');
fork:=1to8dowrite(a[k],'');
writeln;
end;
proceretry(i:integer);
varj:integer;
begin
forj:=1to8do
if(b[j]=0)and(c[i+j]=0)and(d[i-j]=0)then
begin
a:=j;
b[j]:=1;
c[i+j]:=1;
d[i-j]:=1;
ifi<8thentry(i+1)
elseprint;
b[j]:=0;
c[i+j]:=0;
d[i-j]:=0;
end;
end;
begin
fork:=-7to16do
begin
b[k]:=0;
c[k]:=0;
d[k]:=0;
end;
try(1);
end.
==========================================
这是N皇后问题,看看吧:
在N*N的棋盘上,放置N个皇后,要求每一横行每一列,每一对角线上均只能放置一个皇后,问可能的方案及方案数。
const max=8;
var i,j:integer;
a:array[1..max] of 0..max; //放皇后数组
b:array[2..2*max] of boolean; // ‘/’对角线标志数组}
c:array[-(max-1)..max-1] of boolean;// ‘\’对角线标志数组}
col:array[1..max] of boolean; //列标志数组}
total:integer; //统计总数}
procere output; //这里是输出过程
var i:integer;
begin
write('No.':4,'[',total+1:2,']');
for i:=1 to max do write(a[i]:3);write(' ');
if (total+1) mod 2 =0 then writeln; inc(total);
end;
function ok(i,dep:integer):boolean; //判断第dep行第i列可放否?
begin
ok:=false;
if ( b[i+dep]=true) and ( c[dep-i]=true) and
(col[i]=true) then ok:=true
end;
procere try(dep:integer);
var i,j:integer;
begin
for i:=1 to max do //每一行均有max种放法,对吧?xixi~~~~
if ok(i,dep) then begin
a[dep]:=i;
b[i+dep]:=false; // ‘/’对角线已放标志
c[dep-i]:=false; // ‘\’对角线已放标志
col[i]:=false; // 列已放标志
if dep=max then output
else try(dep+1); // 递归下一层
a[dep]:=0; //取走皇后,回溯
b[i+dep]:=true; //恢复标志数组
c[dep-i]:=true;
col[i]:=true;
end;
end;
begin
for i:=1 to max do begin a[i]:=0;col[i]:=true;end;
for i:=2 to 2*max do b[i]:=true;
for i:=-(max-1) to max-1 do c[i]:=true;
total:=0;
try(1);
writeln('total:',total);
end.
I. 八皇后究竟有多少种解法怎么解
这样算是最佳解 class Queen8{ static final int QueenMax = 8; static int oktimes = 0; static int chess[] = new int[QueenMax]; public static void main(String args[]){ for (int i=0;i<QueenMax;i++)chess[i]=-1; placequeen(0); System.out.println("\n\n\n八皇后共有"+oktimes+"个解法 made by yifi 2003"); } public static void placequeen(int num) { int i=0; boolean qsave[] = new boolean[QueenMax]; for(;i<QueenMax;i++) qsave[i]=true; i=0; while (i<num){ qsave[chess[i]]=false; int k=num-i; if ( (chess[i]+k >= 0) && (chess[i]+k < QueenMax) ) qsave[chess[i]+k]=false; if ( (chess[i]-k >= 0) && (chess[i]-k < QueenMax) ) qsave[chess[i]-k]=false; i++; } for(i=0;i<QueenMax;i++){ if (qsave[i]==false)continue; if (num<QueenMax-1){ chess[num]=i; placequeen(num+1); } else{ //num is last one chess[num]=i; oktimes++; System.out.println("这是第"+oktimes+"个解法 如下:"); System.out.println("第n行: 1 2 3 4 5 6 7 8"); for (i=0;i<QueenMax;i++){ String row="第"+(i+1)+"行: "; if (chess[i]==0); else for(int j=0;j<chess[i];j++) row+="--"; row+="++"; int j = chess[i]; while(j<QueenMax-1){row+="--";j++;} System.out.println(row); } } } } } 多少种解法就不好说了..
J. 求~~~pascal八皇后 非递归详细算法和程序
〖问题描述〗
在一个8×8的棋盘里放置8个皇后,要求每个皇后两两之间不相"冲"(在每一横列竖列斜列只有一个皇后)。
〖问题分析〗(聿怀中学吕思博)
这道题可以用递归循环来做,分别一一测试每一种摆法,直到得出正确的答案。主要解决以下几个问题:
1、冲突。包括行、列、两条对角线:
(1)列:规定每一列放一个皇后,不会造成列上的冲突;
(2)行:当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;
(3)对角线:对角线有两个方向。在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。
2、数据结构。
(1)解数组A。A[I]表示第I个皇后放置的列;范围:1..8
(2)行冲突标记数组B。B[I]=0表示第I行空闲;B[I]=1表示第I行被占领;范围:1..8
(3)对角线冲突标记数组C、D。
C[I-J]=0表示第(I-J)条对角线空闲;C[I-J]=1表示第(I-J)条对角线被占领;范围:-7..7
D[I+J]=0表示第(I+J)条对角线空闲;D[I+J]=1表示第(I+J)条对角线被占领;范围:2..16
〖算法流程〗
1、数据初始化。
2、从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领):
如果是,摆放第n个皇后,并宣布占领(记得要横列竖列斜列一起来哦),接着进行递归;
如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,却发现此时已经无法摆放时,便要进行回溯。
3、当n>;8时,便一一打印出结果。
〖优点〗逐一测试标准答案,不会有漏网之鱼。
〖参考程序〗queen.pas
----------------------------------------------------------------------------
programtt;
vara:array[1..8]ofinteger;
b,c,d:array[-7..16]ofinteger;
t,i,j,k:integer;
procereprint;
begin
t:=t+1;
write(t,'');
fork:=1to8dowrite(a[k],'');
writeln;
end;
proceretry(i:integer);
varj:integer;
begin
forj:=1to8do{每个皇后都有8种可能位置}
if(b[j]=0)and(c[i+j]=0)and(d[i-j]=0)then{判断位置是否冲突}
begin
a:=j;{摆放皇后}
b[j]:=1;{宣布占领第J行}
c[i+j]:=1;{占领两个对角线}
d[i-j]:=1;
ifi<8thentry(i+1){8个皇后没有摆完,递归摆放下一皇后}
elseprint;{完成任务,打印结果}
b[j]:=0;{回溯}
c[i+j]:=0;
d[i-j]:=0;
end;
end;
begin
fork:=-7to16do{数据初始化}
begin
b[k]:=0;
c[k]:=0;
d[k]:=0;
end;
try(1);{从第1个皇后开始放置}
end.
==========================================
这是N皇后问题,看看吧:
在N*N的棋盘上,放置N个皇后,要求每一横行每一列,每一对角线上均只能放置一个皇后,问可能的方案及方案数。
const max=8;
var i,j:integer;
a:array[1..max] of 0..max; //放皇后数组
b:array[2..2*max] of boolean; // ‘/’对角线标志数组}
c:array[-(max-1)..max-1] of boolean;// ‘\’对角线标志数组}
col:array[1..max] of boolean; //列标志数组}
total:integer; //统计总数}
procere output; //这里是输出过程
var i:integer;
begin
write('No.':4,'[',total+1:2,']');
for i:=1 to max do write(a[i]:3);write(' ');
if (total+1) mod 2 =0 then writeln; inc(total);
end;
function ok(i,dep:integer):boolean; //判断第dep行第i列可放否?
begin
ok:=false;
if ( b[i+dep]=true) and ( c[dep-i]=true) {and (a[dep]=0)} and
(col[i]=true) then ok:=true
end;
procere try(dep:integer);
var i,j:integer;
begin
for i:=1 to max do //每一行均有max种放法,对吧?xixi~~~~
if ok(i,dep) then begin
a[dep]:=i;
b[i+dep]:=false; // ‘/’对角线已放标志
c[dep-i]:=false; // ‘\’对角线已放标志
col[i]:=false; // 列已放标志
if dep=max then output
else try(dep+1); // 递归下一层
a[dep]:=0; //取走皇后,回溯
b[i+dep]:=true; //恢复标志数组
c[dep-i]:=true;
col[i]:=true;
end;
end;
begin
for i:=1 to max do begin a[i]:=0;col[i]:=true;end;
for i:=2 to 2*max do b[i]:=true;
for i:=-(max-1) to max-1 do c[i]:=true;
total:=0;
try(1);
writeln('total:',total);
end.