回溯法之N皇后问题(C语言)
回溯法解皇后问题

Ch1-绪论1. 回溯法解皇后问题#include "stdio.h"#include "math.h"#include "stdlib.h"void queen(int n){ int i,j,k,jt,*q;q=malloc(n*sizeof(int));for(i=0; i<n; i++) q[i]=0;i=0; jt=1;printf("\n");printf("%d queen problem\n",n);while(jt==1){ if (q[i]<n){ k=0;while((k<i)&&((q[k]-q[i])*(fabs(q[k]-q[i])-fabs(k-i)))!=0) k=k+1;if (k<i) q[i]=q[i]+1;else{ if (i==n-1){ for(j=0; j<n; j++)printf("%5d",q[j]+1);printf("\n");q[n-1]=q[n-1]+1;}else i=i+1;}}else{ q[i]=0; i=i-1;if (i<0){ printf("\n"); free(q); return; }q[i]=q[i]+1;}}}2. 简单二分法求方程实根(1)#include "stdio.h"#include "math.h"double root(a,b,eps,f)double a,b,eps,(*f)();{ double f0,f1,c;f0=(*f)(a);while (fabs(a-b)>=eps){ c=(a+b)/2; f1=(*f)(c);if (f1==0) return(c);if (f0*f1>0) a=c;else b=c;}c=(a+b)/2;return(c);}(2)#include "root.c"main(){ double a,b,eps,f();a=1; b=2; eps=0.000001;printf("x=%7.3f\n",root(a,b,eps,f));}double f(x)double x;{ double y;y=x+log(x)-2.2;return(y);}Ch2-矩阵与线性代数方程组(1)文件头:#include "math.h"#include "stdio.h"int maqr(m,n,a,q)int m,n;double a[],q[];{ int i,j,k,l,nn,p,jj;double u,alpha,w,t;if (m<n){ printf("fail\n"); return(0);}for (i=0; i<=m-1; i++)for (j=0; j<=m-1; j++){ l=i*m+j; q[l]=0.0;if (i==j) q[l]=1.0;}nn=n;if (m==n) nn=m-1;for (k=0; k<=nn-1; k++){ u=0.0; l=k*n+k;for (i=k; i<=m-1; i++){ w=fabs(a[i*n+k]);if (w>u) u=w;}alpha=0.0;for (i=k; i<=m-1; i++){ t=a[i*n+k]/u; alpha=alpha+t*t;}if (a[l]>0.0) u=-u;alpha=u*sqrt(alpha);if (fabs(alpha)+1.0==1.0){ printf("fail\n"); return(0);}u=sqrt(2.0*alpha*(alpha-a[l]));if ((u+1.0)!=1.0){ a[l]=(a[l]-alpha)/u;for (i=k+1; i<=m-1; i++){ p=i*n+k; a[p]=a[p]/u;}for (j=0; j<=m-1; j++){ t=0.0;文件尾:for (jj=k; jj<=m-1; jj++)t=t+a[jj*n+k]*q[jj*m+j];for (i=k; i<=m-1; i++){ p=i*m+j; q[p]=q[p]-2.0*t*a[i*n+k];}}for (j=k+1; j<=n-1; j++){ t=0.0;for (jj=k; jj<=m-1; jj++)t=t+a[jj*n+k]*a[jj*n+j];for (i=k; i<=m-1; i++){ p=i*n+j; a[p]=a[p]-2.0*t*a[i*n+k];}}a[l]=alpha;for (i=k+1; i<=m-1; i++)a[i*n+k]=0.0;}}for (i=0; i<=m-2; i++)for (j=i+1; j<=m-1;j++){ p=i*m+j; l=j*m+i;t=q[p]; q[p]=q[l]; q[l]=t;}return(1);}(2)#include "stdio.h"#include "maqr.c"main(){ int i,j;static double q[4][4],a[4][3]={ {1.0,1.0,-1.0}, {2.0,1.0,0.0},{1.0,-1.0,0.0},{-1.0,2.0,1.0}};i=maqr(4,3,a,q);if (i!=0){ printf("MAT Q IS:\n");for (i=0; i<=3; i++){ for (j=0; j<=3; j++)printf("%13.7e ",q[i][j]);printf("\n");}printf("\n");printf("MAT R IS:\n");for (i=0; i<=3; i++){ for (j=0; j<=2; j++)printf("%13.7e ",a[i][j]);printf("\n");}printf("\n");}}(3)文件头:#include "stdlib.h"#include "math.h"int muav(m,n,a,u,v,eps,ka)int m,n,ka;double eps,a[],u[],v[];{ int i,j,k,l,it,ll,kk,ix,iy,mm,nn,iz,m1,ks;double d,dd,t,sm,sm1,em1,sk,ek,b,c,shh,fg[2],cs[2]; double *s,*e,*w;void ppp();void sss();s=malloc(ka*sizeof(double));e=malloc(ka*sizeof(double));w=malloc(ka*sizeof(double));it=60; k=n;if (m-1<n) k=m-1;l=m;if (n-2<m) l=n-2;if (l<0) l=0;ll=k;if (l>k) ll=l;if (ll>=1){ for (kk=1; kk<=ll; kk++){ if (kk<=k){ d=0.0;for (i=kk; i<=m; i++){ ix=(i-1)*n+kk-1; d=d+a[ix]*a[ix];}s[kk-1]=sqrt(d);if (s[kk-1]!=0.0){ ix=(kk-1)*n+kk-1;if (a[ix]!=0.0){ s[kk-1]=fabs(s[kk-1]);if (a[ix]<0.0) s[kk-1]=-s[kk-1];}for (i=文件尾:{ int i,j,p,q;double d;if (m>=n) i=n;else i=m;for (j=1; j<=i-1; j++){ a[(j-1)*n+j-1]=s[j-1];a[(j-1)*n+j]=e[j-1];}a[(i-1)*n+i-1]=s[i-1];if (m<n) a[(i-1)*n+i]=e[i-1];for (i=1; i<=n-1; i++)for (j=i+1; j<=n; j++){ p=(i-1)*n+j-1; q=(j-1)*n+i-1;d=v[p]; v[p]=v[q]; v[q]=d;}return;}static void sss(fg,cs)double cs[2],fg[2];{ double r,d;if ((fabs(fg[0])+fabs(fg[1]))==0.0){ cs[0]=1.0; cs[1]=0.0; d=0.0;} else{ d=sqrt(fg[0]*fg[0]+fg[1]*fg[1]);if (fabs(fg[0])>fabs(fg[1])){ d=fabs(d);if (fg[0]<0.0) d=-d;}if (fabs(fg[1])>=fabs(fg[0])){ d=fabs(d);if (fg[1]<0.0) d=-d;}cs[0]=fg[0]/d; cs[1]=fg[1]/d;}r=1.0;if (fabs(fg[0])>fabs(fg[1])) r=cs[1];elseif (cs[0]!=0.0) r=1.0/cs[0];fg[0]=d; fg[1]=r;return;}#include "stdio.h"#include "cgauss.c"main(){ int i;static double ar[4][4]={ {1.0,3.0,2.0,13.0},{7.0,2.0,1.0,-2.0},{9.0,15.0,3.0,-2.0},{-2.0,-2.0,11.0,5.0}};static double ai[4][4]={ {3.0,-2.0,1.0,6.0},{-2.0,7.0,5.0,8.0},{9.0,-3.0,15.0,1.0},{-2.0,-2.0,7.0,6.0}}; static double br[4]={2.0,7.0,3.0,9.0};static double bi[4]={1.0,2.0,-2.0,3.0};if (cgauss(4,ar,ai,br,bi)!=0)for (i=0;i<=3;i++)printf("b(%d)=%13.7e +j %13.7e\n",i,br[i],bi[i]); }。
回溯法求解N皇后问题

① 如果xi+1= ai+1k不是集合Si+1的最后一个元素,则令xi+1= ai+ 1k+1,即选择Si+1的下一个元素作为解向量X的第i+1个分量;
② 如果xi+1= ai+1k是集合Si+1的最后一个元素,就回溯到X=(x1, x2, …, xi),选择Si的下一个元素作为解向量X的第i个分量,假 设xi= aik,如果aik不是集合Si的最后一个元素,则令xi= aik+1; 否则,就继续回溯到X=(x1, x2, …, xi-1);
global X(1:k); integer i,k;
i1
while i<k do
if X(i)=X(k) or ABS(X(i)-X(k))=ABS(i-k) then
return (false)
end if
ii+1 repeat return (true)
判断是否有其它的皇 后与之在同一列或同 一斜对角线上
HHIT
Algorithm
(1)如果X=(x1, x2, …, xi+1)是问题的最终解,则输出这个解。 如果问题只希望得到一个解,则结束搜索,否则继续搜索其
他解;
(2)如果X=(x1, x2, …, xi+1)是问题的部分解,则继续构造解 向量的下一个分量;
(3)如果X=(x1, x2, …, xi+1)既不是问题的部分解也不是问题 的最终解,则存在下面两种情况:
while k>0 do // 对所有的行,执行以下语句 //
X(k)X(k)+1 //移到下一列//
while X(k)<=n and Not PLACE(k) do //此处能放这个皇后吗//
X(k)X(k)+1 //不能放则转到下一列//
实验四回溯法求n皇后问题

return true;
}
void queue(intn)
{
inti,k;
for(i=1;i<=n;i++)
x[i]=0;
k=1;
while(k>=1)
{
x[k]=x[k]+1; //在下一列放置第k个皇后
while(x[k]<=n&&!place(k))
x[k]=x[k]+1;//搜索下一列
k=k+1;//放置下一个皇后
else
{
x[k]=0;//重置x[k],回溯
k=k-1;
}
}
}
void main()
{
intn;
printf("输入皇后个数n:\n");
scanf("%d",&n);
queue(n);
}
五、实验结果截图
六、实验总结
关于n皇后问题,看似复杂难懂,运行结果也很多,但是如果掌握了算法的要点,并且编写的准确无误,其实很简单明了的,而且在组实验的过程中会体会到很多乐趣,当然也有不懂得地方,需要请教别人,总之受益匪浅。
if(x[k]<=n&&k==n)//得到一个输出
{
for(i=1;i<=n;i++)
printf("%d ",x[i]);
printf("\n");
//return;//若return则只求出其中一种解,若不return则可以继续回溯,求出全部的可能的解
}
else if(x[k]<=n&&k<n)
n皇后问题递归算法c语言

n皇后问题递归算法c语言概述n皇后问题是一个经典的回溯算法问题,它要求在一个n×n的棋盘上放置n个皇后,使得它们互不攻击。
本文将使用递归算法来解决n皇后问题,并使用C语言进行实现。
问题描述在n×n的棋盘上放置n个皇后,使得它们不在同一行、同一列或同一斜线上。
其中,皇后的移动规则是可以横向、纵向、对角线方向上自由移动任意步数。
算法思路为了解决n皇后问题,我们可以采用递归的方式逐行放置皇后。
具体地,可以按照行优先的顺序,从第一行开始放置皇后,并逐行向下递归,直到放置了n个皇后,或者无法再放置皇后为止。
算法的关键在于如何判断当前位置是否可以放置皇后,即判断是否与已经放置的皇后位置冲突。
为了判断冲突,我们需要考虑以下几个方面:1.所有皇后不能在同一列:我们可以使用一个数组q ue en[]来记录每一行放置的皇后的列位置。
2.所有皇后不能在同一对角线上:我们可以使用两个数组up D ia g[]和d ow nD ia g[]来记录每一条对角线上是否已经存在皇后。
对于任意一个位置(i,j),它所在的主对角线上的元素满足i-j的值相等,次对角线上的元素满足i+j的值相等。
在放置皇后时,我们可以逐个尝试每一列,然后检查当前位置是否与已经放置的皇后位置冲突,如果冲突则继续尝试下一列,直到找到一个合适的位置。
然后,继续递归放置下一行的皇后,直到放置了n个皇后或者无法再放置为止。
伪代码定义一个全局整型数组q ue en[],用于记录每一行放置的皇后的列位置定义两个全局整型数组u pD ia g[]和do wn D ia g[],用于记录每一条对角线上是否已经存在皇后P r oc ed ur en Qu ee ns(r ow):i f ro w=n://找到一个解P r in tS ol ut io n()r e tu rnf o rc ol fr om0t on-1:i f Ca nP la ce Qu ee n(r o w,co l):P l ac eQ ue en(r ow,co l)n Q ue en s(ro w+1)R e mo ve Qu ee n(ro w,c o l)P r oc ed ur eC an Pl ace Q ue en(r ow,c ol):i f qu ee n[co l]!=-1:r e tu rn fa ls ei f up Di ag[r ow-c ol+n-1]!=-1o rd ow nDi a g[ro w+co l]!=-1:r e tu rn fa ls er e tu rn tr ueP r oc ed ur eP la ce Que e n(ro w,co l):q u ee n[co l]=r owu p Di ag[r ow-c ol+n-1]=1d o wn Di ag[r ow+c ol]=1q u ee n[co l]=-1u p Di ag[r ow-c ol+n-1]=-1d o wn Di ag[r ow+c ol]=-1P r oc ed u r eP ri nt Sol u ti on():f o rr ow fr om0t on-1:f o rc ol fr om0t on-1:i f qu ee n[co l]=r ow:p r in t"Q"e l se:p r in t"*"p r in tn ew li nep r in tn ew li neC语言实现下面是使用C语言实现的n皇后问题递归算法的代码示例:#i nc lu de<s td io.h>#d ef in eN8i n tq ue en[N];//记录每一行放置的皇后的列位置i n tu pD ia g[2*N-1];//记录每一条对角线上是否已经存在皇后i n td ow nD ia g[2*N-1];//记录每一条对角线上是否已经存在皇后v o id nQ ue en s(in tro w);i n tc an Pl ac eQ ue en(i nt ro w,in tc ol);v o id pl ac eQ ue en(in t ro w,in tc ol);v o id pr in tS ol ut ion();i n tm ai n(){f o r(in ti=0;i<N;i++){q u ee n[i]=-1;}f o r(in ti=0;i<2*N-1;i++){u p Di ag[i]=-1;d o wn Di ag[i]=-1;}n Q ue en s(0);r e tu rn0;}v o id nQ ue en s(in tro w){i f(r ow==N){p r in tS ol ut io n();r e tu rn;}f o r(in tc ol=0;c ol<N;c ol++){ i f(c an Pl ac eQ ue en(r ow,c ol)){ p l ac eQ ue en(r ow,co l);n Q ue en s(ro w+1);r e mo ve Qu ee n(ro w,c o l);}}}i n tc an Pl ac eQ ue en(i nt r o w,in tc ol){i f(q ue en[c ol]!=-1){r e tu rn0;}i f(u pD ia g[ro w-col+N-1]!=-1||do wnD i ag[r ow+c ol]!=-1){ r e tu rn0;}r e tu rn1;}v o id pl ac eQ ue en(in t ro w,in tc ol){q u ee n[co l]=r ow;u p Di ag[r ow-c ol+N-1]=1;d o wn Di ag[r ow+c ol]=1;}v o id re mo ve Qu ee n(i n tr ow,i nt co l){q u ee n[co l]=-1;u p Di ag[r ow-c ol+N-1]=-1;d o wn Di ag[r ow+c ol]=-1;}v o id pr in tS ol ut ion(){f o r(in tr ow=0;r ow<N;r ow++){f o r(in tc ol=0;c ol<N;c ol++){i f(q ue en[c ol]==ro w){p r in tf("Q");}e ls e{p r in tf("*");}}p r in tf("\n");}p r in tf("\n");}总结本文使用C语言实现了n皇后问题的递归算法。
回溯法求N皇后问题

Tree-回溯法求N皇后问题#include <stdio.h>#include <malloc.h>#define N 4 //N皇后typedef int Chessboard[N + 1][N + 1]; //第0号位置不用bool check(Chessboard cb, int i, int j) { //看棋盘cb是否满足合法布局int h, k;int m = i + j, n = i - j;for(h=1; h<i; h++) {if(cb[h][j] == 1 && h != i) return false; //检查第j列if(m-h<=N && cb[h][m-h] == 1 && h != i) return false; //检查斜的,m-h<=N是为了保证不越界if(h-n<=N && cb[h][h-n] == 1 && h != i) return false; //检查斜的,h-n<=N是为了保证不越界}for(k=1; k<N; k++)/*检查第i行的*/ if(cb[i][k] == 1 && k != j) return false;return true;}void printfChessboard(Chessboard cb) {//打印棋盘int i, j;for(i=1; i<=N; i++) {for(j=1; j<=N; j++) printf("%d ", cb[i][j]);printf("\n");}printf("\n");}/*进入本函数时,在n*n棋盘前n-1行已放置了互不攻击的i-1个棋子。
现从第i行起继续为后续棋子选择合适位置。
回溯典型题目——N皇后问题剖析

N皇后问题问题描述:在N*N的方格中放置N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上)对于给定的N,输出摆放方案并求出有多少种合法的放置方法。
【假设N<=10】基础:四皇后问题我们先来看看四皇后问题,在一个4*4的棋盘中摆放4个皇后,四个皇后不能摆在互相攻击的位置。
方案一:回溯法(程序中包含递归和深搜)源代码://四皇后问题:回溯#include <stdio.h>#include <string>int flag[4][4]; //用于标记放过的棋子//n个皇后,深搜int count=0;int iscorrect(int i,int j){ //判断是否可以放置棋子int a,b;for(a=i,b=0;b<4;b++){if(flag[a][b]==1) //说明在同一行有棋子return 0;}for(a=0,b=j;a<4;a++){if(flag[a][b]==1) //说明在同一行有棋子return 0;}for(a=i-1,b=j-1;a>=0&&b>=0;a--,b--){ //左上方if(flag[a][b]==1)return 0;}for(a=i-1,b=j+1;a>=0&&b<=3;a--,b++){ //左下方if(flag[a][b]==1)return 0;}for(a=i+1,b=j-1;a<=3&&b>=0;a++,b--){ //右上方if(flag[a][b]==1)return 0;}for(a=i+1,b=j+1;a<=3&&b<=3;a++,b++){ //判断右下方if(flag[a][b]==1)return 0;}return 1;}void DFSQ(int i){int m,n;int j;//i代表行数,j代表列数if(i==4){ //因为棋盘是(n-1)*(n-1)模式的,而i是行,当棋盘到第四行的时候,表明已//经完成0~3的所有排布已经完成for(m=0;m<4;m++){for(n=0;n<4;n++){printf("%d ",flag[m][n]);}printf("\n");}count++;printf("\n");return; //不要忘记这个}else{for(j=0;j<4;j++){if(iscorrect(i,j)){ //如果可以放置棋子flag[i][j]=1; //标记flag[i][j]DFSQ(i+1); //递归调用flag[i][j]=0; //消除标记}}}}int main(){memset(flag,0,sizeof(flag));DFSQ(0);printf("count=%d\n",count);return 0;}其实从四皇后问题拓展到n皇后问题是非常简单的事情,方案一进阶到N皇后的源代码:N皇后其实只要把其中的4改成N就行了:源代码:#include <stdio.h>#include <string>int flag[10][10]; //用于标记放过的棋子int number; //表示棋子个数//n个皇后,深搜int count=0;int iscorrect(int i,int j){ //判断是否可以放置棋子int a,b;for(a=i,b=0;b<number;b++){if(flag[a][b]==1) //说明在同一行有棋子return 0;}for(a=0,b=j;a<number;a++){if(flag[a][b]==1) //说明在同一行有棋子return 0;}for(a=i-1,b=j-1;a>=0&&b>=0;a--,b--){ //左上方if(flag[a][b]==1)return 0;}for(a=i-1,b=j+1;a>=0&&b<=number-1;a--,b++){ //左下方if(flag[a][b]==1)return 0;}for(a=i+1,b=j-1;a<=number-1&&b>=0;a++,b--){ //右上方if(flag[a][b]==1)return 0;}for(a=i+1,b=j+1;a<=number-1&&b<=number-1;a++,b++){ //判断右下方if(flag[a][b]==1)return 0;}return 1;}void DFSQ(int i){int m,n;int j;//i代表行数,j代表列数if(i==number){ //因为棋盘是(n-1)*(n-1)模式的,而i是行,当棋盘到第四行的时候,表明已经完成0~number-1的所有排布已经完成for(m=0;m<number;m++){for(n=0;n<number;n++){printf("%d ",flag[m][n]);}printf("\n");}count++;printf("\n");return; //不要忘记这个}else{for(j=0;j<number;j++){if(iscorrect(i,j)){ //如果可以放置棋子flag[i][j]=1; //标记flag[i][j]DFSQ(i+1); //递归调用flag[i][j]=0; //消除标记}}}}int main(){scanf("%d",&number);memset(flag,0,sizeof(flag));DFSQ(0);printf("count=%d\n",count);return 0;}。
回溯法解决N皇后问题C语言

回溯法解决N皇后问题C语⾔问题描述:⼋皇后问题是⼀个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置⼋个皇后,使得任何⼀个皇后都⽆法直接吃掉其他的皇后?为了达到此⽬的,任两个皇后都不能处于同⼀条横⾏、纵⾏或斜线上。
回溯法:回溯法⼜称试探法。
回溯法的基本做法是深度优先搜索。
即从⼀条路往前⾛,能进则进,不能进则退回来,换⼀条路再试。
源代码:#include<stdio.h>#include<math.h>int x[9]={0};bool PLACE(int k)//检测第k个皇后能否放进棋盘{int i=1;while(i<k){if(x[i]==x[k]||fabs(x[i]-x[k])==fabs(i-k))return false;i++;}return true;}void NQUEENS(int n){int i,k=1; //k为当前⾏号x[1]=0;//x[k]为第k⾏皇后所放的列号while(k>0){x[k]++;while(x[k]<=n&&!PLACE(k))//该⾏不符合,则放⼊下⼀⾏x[k]++;if(x[k]<=n){if(k==n)//输出x[]{for(i=1;i<=n;i++)printf("x[%d]:%d ",i,x[i]);printf("\n");}else//判断下⼀⾏{k++; x[k]=0;}}else k--;//没找到,则回溯}return ;}int main(){NQUEENS(8);return0;}。
C语言回溯法解八皇后问题(八皇后算法)

C语⾔回溯法解⼋皇后问题(⼋皇后算法)⼋皇后问题(N皇后问题)的回溯法求解⼀、问题描述在⼀个国际象棋棋盘上放置⼋个皇后,使得任何两个皇后之间不相互攻击,求出所有的布棋⽅法,并推⼴到N皇后情况。
⼆、参考资料啥⽂字都不⽤看,B站上有个⾮常详细的动画视频解说,上链接三、源代码#include<iostream>#include<vector>#include<string>using namespace std;void put_queen(int x, int y, vector<vector<int>>&attack){//实现在(x,y)放置皇后,对attack数组更新,xy表⽰放置皇后的坐标,attack表⽰是否可以放置皇后//⽅向数组,⽅便后⾯对8个⽅向进⾏标记static const int dx[] = { -1,-1,-1,0,0,1,1,1 };static const int dy[] = { -1,0,1,-1,1,-1,0,1 };attack[x][y] = 1;//将皇后位置标记为1//通过两层for循环,将该皇后可能攻击到的位置标记for (int i = 1; i < attack.size(); i++)//从皇后位置向1到n-1个距离延伸{for (int j = 0; j < 8; j++)//遍历8个⽅向{int nx = x + i * dx[j];//⽣成的新位置⾏int ny = y + i * dy[j];//⽣成的新位置列//在棋盘范围内if (nx >= 0 && nx < attack.size() && ny >= 0 && ny < attack.size())attack[nx][ny] = 1;//标记为1}}}//回溯算法//k表⽰当前处理的⾏//n表⽰n皇后问题//queen存储皇后的位置//attack标记皇后的攻击范围//solve存储N皇后的全部解法void backtrack(int k, int n, vector<string>& queen,vector<vector<int>>& attack,vector<vector<string>>& solve){if (k == n)//找到⼀组解{solve.push_back(queen);//将结果queen存储⾄solvereturn;}//遍历0⾄n-1列,在循环中,回溯试探皇后可放置的位置for (int i = 0; i < n; i++){if (attack[k][i] == 0)//判断当前k⾏第i列是否可以放置皇后{vector<vector<int>> tmp = attack;//备份attack数组queen[k][i] = 'Q';//标记该位置为Qput_queen(k, i, attack);//更新attack数组backtrack(k + 1, n, queen, attack, solve);//递归试探k+1⾏的皇后的位置attack = tmp;//恢复attack数组queen[k][i] = '.';//恢复queen数组}}}vector<vector<string>>solveNQueens(int n){//string存储具体的摆放位置,<vector<string>>存放⼀种解法,⼆维vector存放全部解法vector<vector<string>>solve;//存储最后结果vector<vector<int>>attack;//标记皇后的攻击位vector<string>queen;//保存皇后位置//使⽤循环初始化attack和queen数组for (int i = 0; i < n; i++){attack.push_back((vector<int>()));for (int j = 0; j < n; j++){attack[i].push_back(0);}queen.push_back("");queen[i].append(n, '.');}backtrack(0, n, queen, attack, solve);return solve;//返回结果数组}int main(){//int num;//cin >> num;//输⼊皇后数初始化attack数组//vector<vector<int>> attack(num,vector<int>(num, 0));初始化queen数组//string s;//for (int i = 0; i < num; i++)s += '.';//vector<string> queen(num, s);int n;cin >> n;vector<vector<string>>result;result = solveNQueens(n);cout << n << "皇后共有" << result.size() << "种解法" << endl;for (int i = 0; i < result.size(); i++){cout << "解法" << i + 1 << ":" << endl;for (int j = 0; j < result[i].size(); j++){cout << result[i][j] << endl;}cout << endl;}system("pause");return 0;}四、测试结果四皇后⼋皇后到此这篇关于C语⾔回溯法解⼋皇后问题的⽂章就介绍到这了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//回溯法之N皇后问题当N>10,就有点抽了~~
/*结果前total行每行均为一种放法,表示第i行摆放皇后的列位置,第total+1行,输出total*/
#include<stdio.h>
#include<stdlib.h>
int n,stack[100]; //存当前路径
int total; //路径数
void make(int l) //递归搜索以stack[l]为初结点的所有路径
{
int i,j; //子结点个数
if (l==n+1)
{
total=total+1; //路径数+1
for(i=1;i<=n;i++)
printf("%-3d",stack[i]); //输出第i行皇后的列位置stack[i] printf("\n");
exit; //回溯(若试题仅要求一条路径,则exit改为halt即可)}
for (i=1;i<=n;i++)
{
stack[l]=i; //算符i作用于生成stack[l-1]产生子状态stack[l];
if (!att(l,i)) make(l+1);
} //再无算符可用,回溯
}
int att(int l,int i)
{
int k;
for (k=1;k<l;k++)
if (abs(l-k)==abs(stack[k]-i)||i==stack[k]) return 1;
return 0;
}
int main()
{
printf("N=");
scanf("%d",&n);
total=0; //路径数初始化为0
make(1); //从结点1出发,递归搜索所有的路径
printf("%d\n",total);
system("pause");
return 0;
}
由回溯法的算法流程可以看出,除非边界条件设置不当而导致死循环外,回溯法一般是不会产生内存溢出的。
但是,回溯法亦有其致命的弱点——时间效率
比数学解析法低。
为了改善其时效,我们可以从下述几个方面考虑优化:
1、递归时对尚待搜索的信息进行预处理,减少搜索量;
2、尽可能减少分支(解答树的次数);
3、增加约束条件,使其在保证出解的前提下尽可能“苛刻”;
4、在约束条件中设置限定搜索层次的槛值。