八皇后问题求解的C语言程序的实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了八皇后问题求解的C语言程序的实现相关的知识,希望对你有一定的参考价值。
若为n皇后问题就是在n*n的棋盘上放置n个皇后 。
〔基本要求〕八皇后问题是一个古老的搜索问题,可以用递归算法来实现,在递归过程中,一一测试每一种放法,直到得出全部正确答案为止。
〔实现提示〕定义一个8*8的二维数组(为方便处理,下标范围为1:8为好);
对数组进行初始化;(全置空)
从n行开始放置第一个皇后(满足一行只有一个皇后的要求)后
对1~8列进行测试;若满足条件则保存皇后所在位置,直到所有皇后放置好;
输出每一个皇后应放置的位置
八皇后问题共有92种解;
以下代码是解决:对于固定一个皇后位置,输出所有可能情况.
如果这不适合你的答案你可以,稍微改改的哦~~
代码如下:
#include "stdio.h"
bool board[8][8]=0;
int num=0; //满足条件的个数
int inix,iniy; //输入一个皇后的初始位置
void output() //输出
int i, j;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
if(!board[i][j]) printf("■ ");
else printf("◆ ");
printf("\n");
num++;
printf("\n\n");
return ;
bool check(int x,int y) //判断是否能放
int i, j ;
for(i=0; i<8 ; i++)
if(board[i][y]==1) return false;
for(i=0;i<8;i++)
if(board[x][i]==1) return false;
i=x; j=y;
while(i>0 && j>0 ) i--; j--;
for(;i<8 && j<8 ; i++,j++)
if(board[i][j]==1) return false;
i=x; j=y;
while(i>0 && j<7 ) i--;j++;
for(;i<8 && j>=0 ; i++ ,j--)
if(board[i][j]==1) return false ;
return true ;
void search(int x,int num) // 搜索函数
int i;
if(num>=8) output(); return ;
if(x==inix-1) search(inix,num+1);
else
for(i=0;i<8;i++)
if(check(x,i))
board[x][i]=1;
search(x+1,num+1);
board[x][i]=0;
return ;
int main()
scanf("%d %d",&inix,&iniy);
board[inix-1][iniy-1] = 1 ;
search(0,0);
printf("%d\n",num);
return 0;
例如:
输入 : 1 1
输出 :
◆ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ◆ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ◆
■ ■ ■ ■ ■ ◆ ■ ■
■ ■ ◆ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ◆ ■
■ ◆ ■ ■ ■ ■ ■ ■
■ ■ ■ ◆ ■ ■ ■ ■
◆ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ◆ ■ ■
■ ■ ■ ■ ■ ■ ■ ◆
■ ■ ◆ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ◆ ■
■ ■ ■ ◆ ■ ■ ■ ■
■ ◆ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ◆ ■ ■ ■
◆ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ◆ ■
■ ■ ■ ◆ ■ ■ ■ ■
■ ■ ■ ■ ■ ◆ ■ ■
■ ■ ■ ■ ■ ■ ■ ◆
■ ◆ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ◆ ■ ■ ■
■ ■ ◆ ■ ■ ■ ■ ■
◆ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ◆ ■
■ ■ ■ ■ ◆ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ◆
■ ◆ ■ ■ ■ ■ ■ ■
■ ■ ■ ◆ ■ ■ ■ ■
■ ■ ■ ■ ■ ◆ ■ ■
■ ■ ◆ ■ ■ ■ ■ ■
4 参考技术A 此程序可解决N后问题,但输出效果没有上面的好
#include<iostream.h>
const int N = 20;
void main()
cout<<"n后问题\n\n";
int n, m, good, col[N+1], a[N+1], b[2*N+1], c[2*N+1], j;
cout<<"n = "; cin>>n;
for(j = 0; j <= n; j++) a[j] = 1;
for(j = 0; j <= 2*n; j++) b[j] = c[j] = 1;
m = col[1] = good = 1; col[0]=0;
do
if(good)
if(m == n)
cout<<"\n 列 行\n";
for(j = 1; j <= n; j++)
cout<<" "<<j<<" "<<col[j]<<endl;;
while(col[m] == n)
m--;
a[col[m]] = b[m+col[m]] = c[n+m-col[m]] = 1;
col[m]++;
else // m==n
a[col[m]] = b[m+col[m]] = c[n+m-col[m]] = 0;
col[++m] = 1;
else //good
while(col[m] == n)
m--;
a[col[m]] = b[m+col[m]] = c[n+m-col[m]] = 1;
col[m]++;
// end good
good = a[col[m]] && b[m+col[m]] && c[n+m-col[m]];
while(m);
cin>>n;
参考技术B #include<stdio.h>
int q[20];
void Queens(int,int);
int Place(int,int);
void print(int);
int main()
int n;
printf("您要求的是几皇后问题?\n");
scanf("%d",&n);
Queens(1,n);
system("pause");
return 0;
void Queens(int k,int n)
int i;
if(n<k)
print(n);
else
for(i=1;i<=n;i++)
if(Place(i,k)==1)
q[k]=i;
Queens(k+1,n);
int Place(int i,int k)
int j=1;
while(j<k)
if((q[j]==i)||abs(q[j]-i)==abs(j-k))
return 0;
j++;
return 1;
void print(int n)
int i;
for(i=1;i<=n;i++)
printf("<%d,%d>\t",i,q[i]);
printf("\n");
求解八皇后问题的退火算法
这个算法收敛速度还算满意。此算法可以计算n皇后问题,只需要将n改为相应整数即可!
主程序:
clear; clc; %% %八皇后问题,8X8的棋盘上,放置8个皇后,使之两两都不能攻击 %使用退火算法计算 %初始的状态,随机在棋盘上放置8个皇后,每列放一个,使每一行都不能攻击 n = 8; %8皇后 %% %产生一个随机的状态 state = randperm(n); %% %计算当前状态的h函数值(与目标状态的差距,h越大,差距越大。h=0代表此状态即为目标状态) h = fun_c(state); disp(state); disp([‘初始状态的h为‘,num2str(h)]); %% %用退火算法从初始状态产生新的状态 %从时间1开始,t代表时间 t = 1; t_max = 1e5; %允许循环的最大时间 plt = zeros(3,t_max); while t < t_max && h ~=0 %交换现在状态中的任意两个数 i_rand = 1; j_rand = 1; while i_rand == j_rand i_rand = randi(n); j_rand = randi(n); end state_tmp = state; tmp = state_tmp(i_rand); state_tmp(i_rand) = state_tmp(j_rand); state_tmp(j_rand) = tmp; h_tmp = fun_c(state_tmp); if h_tmp <= h state = state_tmp; h = h_tmp; elseif h_tmp > h T = fun_temp(t); % 当前温度 %温度越高,增加的能量越低,此状态的概率越大 p = exp(-(h_tmp-h)*500/T); %有一定的概率接受此状态 if p > rand(1) state = state_tmp; h = h_tmp; end end plt(1,t) = t; plt(2,t) = fun_temp(t); plt(3,t) = h; t = t + 1; end figure(1); axis auto; plot(plt(1,1:(t-1)),plt(2,1:(t-1)),‘b‘); %t VS T hold on; plot(plt(1,1:(t-1)),100*plt(3,1:(t-1)),‘r‘); %t VS h hold off; %% if h == 0 disp(‘退火算法成功‘); else disp(‘退火算法失败‘); end disp([‘经历的时间为‘,num2str(t)]); disp([‘最终状态的h为‘,num2str(h)]); disp(state); %将state转换成nXn矩阵 state_full = zeros(n,n); for i=1:n for j=1:n if j == state(i) state_full(i,j) = 1; end end end %% %显示最终的状态 disp(state_full);
各子函数
function [h] = fun_c(state) %根据一个状态,评价它的代价函数 h = 0; n = length(state); %% %每列的状态,看有多少个能互相攻击,每两两攻击算一次 for i=1:n count = length(find(state == i)); if count > 1; h = h + nchoosek(count,2); end end %% %将state转换成nXn矩阵 state_full = zeros(n,n); for i=1:n for j=1:n if j == state(i) state_full(i,j) = 1; end end end %% %每个左斜对角的状态,看有多少个能互相攻击,每两两攻击算一次 i=1; j=1; add = 0; while i<n+1 && j<n+1 && i>0 && j>0 %计算左斜对角每条线有多少个皇后 count = fun_calc_left(i,j,n,state_full); if count > 1; h = h + nchoosek(count,2); end if add == 0; j = j + 1; elseif add == 1; i = i + 1; end add = ~add; end %% %每个右斜对角的状态,看有多少个能互相攻击,每两两攻击算一次 i=1; j=n; add = 0; while i<n+1 && j<n+1 && i>0 && j>0 %计算右斜对角有多少个皇后 count = fun_calc_right(i,j,n,state_full); if count > 1; h = h + nchoosek(count,2); end if add == 0; j = j - 1; elseif add == 1; i = i + 1; end add = ~add; end end
function count = fun_calc_left(i,j,n,state_full) %% %统计i,j 点,左下角 count = 0; i_l = i; i_r = i; j_l = j; j_r = j; while i_l>0 && j_l>0 && i_l<n+1 && j_l<n+1 count = count + state_full(i_l,j_l); i_l = i_l + 1; j_l = j_l - 1; end %% %右上角的个数 while i_r>0 && j_r>0 && i_r<n+1 && j_r<n+1 count = count + state_full(i_r,j_r); i_r = i_r - 1; j_r = j_r + 1; end %% %被重复加的,减去 count = count - state_full(i,j); end
function count = fun_calc_right(i,j,n,state_full) %% %统计i,j 点,左上角 count = 0; i_l = i; i_r = i; j_l = j; j_r = j; while i_l>0 && j_l>0 && i_l<n+1 && j_l<n+1 count = count + state_full(i_l,j_l); i_l = i_l - 1; j_l = j_l - 1; end %% %右下角的个数 while i_r>0 && j_r>0 && i_r<n+1 && j_r<n+1 count = count + state_full(i_r,j_r); i_r = i_r + 1; j_r = j_r + 1; end %% %被重复加的,减去 count = count - state_full(i,j); end
function T = fun_temp(t) %给定退火的时间和速率,t为时间,T为温度 if t<= 50 T = 1000; elseif t>50 && t<1000 T = 1000 - ( t - 50 )*100/95; else T = 1e-3; end end
以上是关于八皇后问题求解的C语言程序的实现的主要内容,如果未能解决你的问题,请参考以下文章