计算机算法分析与设计(第四版)习题算法分析部分详解(实验六)
- 格式:docx
- 大小:39.15 KB
- 文档页数:16
《算法分析与设计》实验问题详解1.算法实验(1)算法与程序(2)实验中应考虑的问题a)算法:多种方案b)程序:核心程序与相关程序(包括主控程序)c)数据:数据特征、数据量、数据获取方式结果数据文件操作d)运行时间e)多方案对比:数据与比较(3)实验正确性与完备性(4)实验方案设计(5)程序设计(6)实验实例:百钱买百鸡问题基本算法实验设计与实验方案PROGRAM 百钱买百鸡()Integer M=100Integer x, y, z, n, kInteger t1, t2t1←gettime()For k←1 to M do //控制重复次数//n←0For x←0 to 100 doFor y←0 to 100 doFor z←0 to 100 doIf 5*x + 3*y + z/3 = 100 and x + y + z = 100Thenn←n+1print(n, x, y, z)endifrepeatrepeatrepeatrepeatt2←gettime()print((t2 - t1)/M) //取计算平均值,消除噪声//END.实验程序2.文件操作(1)文件类型:文本文件与二进制文件(2)写文件(3)查看文件内容(4)读数据与读文件(5)文件操作程序例写文件程序例/*写文件.cpp*/#include <stdio.h>#include <process.h>FILE *stream;int i = 10 ;double fp = 1.5 ;char *s = "this is a string" ;char c = '\n' ;void main(){stream = fopen( "test1.txt" , "w" ) ;fprintf( stream, "%s%c" , s , c ) ;fprintf( stream, "%d\n" , i ) ;fprintf( stream, "%f\n" , fp ) ;fclose( stream );}写随机数据到文件/*写随机数据到文件.cpp*/#include <stdio.h>#include <stdlib.h>#include <process.h>#include <time.h>#define maxline 1000FILE *stream;void main(){int i , j ;int rd;printf( "请输入一个随机种子:" );i = scanf("%d", &rd ) ;srand( rd );stream = fopen( "test2.txt" , "w" ) ;for ( i=1; i<=maxline; i++ ) {for ( j=1; j<=10; j++)fprintf( stream, "%6d " , rand() ) ;fprintf( stream, "\n " ) ;}fclose( stream );}读文件/*读文件数据.cpp*/#include <stdio.h>#include <stdlib.h>#include <process.h>FILE *stream;void main(){int i , j ;int a ;stream = fopen( "test2.txt" , "r" ) ;for ( i=1; i<=10; i++ ) {for ( j=1; j<=10; j++) {fscanf( stream, "%d " , &a ) ;printf( "%d ",a);}printf( "\n " ) ;}fclose( stream );}3.实验数据设计与准备(2)实验数据设计:正常数据,边界数据,异常数据(3)实验数据准备:人工设计随机函数与随机生成(4)数据准备程序和数据文件4.实验数据的输入与输出(1)数据输入从键盘输入从文件输入(2)数据输出输出到屏幕输出到文件5.机器时钟与运行时间获取(1)机器时钟(2)计算时间(3)误差和精度(4)计算时间获取(5)噪声消除6.实验报告(1)报告基本样式(2)报告内容(3)实验报告要求(4)写作技巧附录一实验报告样式《算法分析与设计》实验报告实验X XXXXXX姓名XXX 学号1234567890 班级xxxx班时间地点同组人指导教师实验目的1、2、3、实验内容1、2、3、实验环境硬件:软件:实验前准备1、算法设计2、程序设计3、数据准备实验步骤1、2、……….实验结果及其分析1、程序运行现象观察2、实验中的问题及解决方法3、程序运行结果4、时空分布图5、运行结果分析6、实际结果与预测对比分析……….。
4.1:在我们所了解的早期排序算法之中有一种叫做Maxsort 的算法。
它的工作流程如下:首先在未排序序列(初始时为整个序列)中选择其中最大的元素max ,然后将该元素同未排序序列中的最后一个元素交换。
这时,max 元素就包含在由每次的最大元素组成的已排序序列之中了,也就说这时的max 已经不在未排序序列之中了。
重复上述过程直到完成整个序列的排序。
(a) 写出Maxsort 算法。
其中待排序序列为E ,含有n 个元素,脚标为范围为0,,1n -K 。
void Maxsort(Element[] E) { int maxID = 0;for (int i=E.length; i>1; i--) { for (int j=0; j<i; j++) {if (E[j] > E[maxID]) maxID = k; E[i] <--> E[maxID];(b) 说明在最坏情况下和平均情况下上述算法的比较次数。
最坏情况同平均情况是相同的都是11(1)()2n i n n C n i -=-==∑。
4.2:在以下的几个练习中我们研究一种叫做“冒泡排序”的排序算法。
该算法通过连续几遍浏览序列实现。
排序策略是顺序比较相邻元素,如果这两个元素未排序则交换这两个元素的位置。
也就说,首先比较第一个元素和第二个元素,如果第一个元素大于第二个元素,这交换这两个元素的位置;然后比较第二个元素与第三个元素,按照需要交换两个元素的位置;以此类推。
(a)起泡排序的最坏情况为逆序输入,比较次数为11(1)()2n i n n C n i -=-==∑。
(b) 最好情况为已排序,需要(n-1)次比较。
4.3: (a)归纳法:当n=1时显然成立,当n=2时经过一次起泡后,也显然最大元素位于末尾;现假设当n=k-1是,命题也成立,则当n=k 时,对前k-1个元素经过一次起泡后,根据假设显然第k-1个元素是前k-1个元素中最大的,现在根据起泡定义它要同第k 个元素进行比较,当k 元素大于k-1元素时,它为k 个元素中最大的,命题成立;当k 元素小于k-1元素时,它要同k-1交换,这时处于队列末尾的显然时队列中最大的元素。
第一章作业1.证明下列Ο、Ω和Θ的性质1)f=Ο(g)当且仅当g=Ω(f)证明:充分性。
若f=Ο(g),则必然存在常数c1>0和n0,使得∀n≥n0,有f≤c1*g(n)。
由于c1≠0,故g(n) ≥ 1/ c1 *f(n),故g=Ω(f)。
必要性。
同理,若g=Ω(f),则必然存在c2>0和n0,使得∀n≥n0,有g(n) ≥ c2 *f(n).由于c2≠0,故f(n) ≤ 1/ c2*f(n),故f=Ο(g)。
2)若f=Θ(g)则g=Θ(f)证明:若f=Θ(g),则必然存在常数c1>0,c2>0和n0,使得∀n≥n0,有c1*g(n) ≤f(n) ≤ c2*g(n)。
由于c1≠0,c2≠0,f(n) ≥c1*g(n)可得g(n) ≤ 1/c1*f(n),同时,f(n) ≤c2*g(n),有g(n) ≥ 1/c2*f(n),即1/c2*f(n) ≤g(n) ≤ 1/c1*f(n),故g=Θ(f)。
3)Ο(f+g)= Ο(max(f,g)),对于Ω和Θ同样成立。
证明:设F(n)= Ο(f+g),则存在c1>0,和n1,使得∀n≥n1,有F(n) ≤ c1 (f(n)+g(n))= c1 f(n) + c1g(n)≤ c1*max{f,g}+ c1*max{f,g}=2 c1*max{f,g}所以,F(n)=Ο(max(f,g)),即Ο(f+g)= Ο(max(f,g))对于Ω和Θ同理证明可以成立。
4)log(n!)= Θ(nlogn)证明:∙由于log(n!)=∑=n i i 1log ≤∑=ni n 1log =nlogn ,所以可得log(n!)= Ο(nlogn)。
∙由于对所有的偶数n 有,log(n!)= ∑=n i i 1log ≥∑=n n i i 2/log ≥∑=nn i n 2/2/log ≥(n/2)log(n/2)=(nlogn)/2-n/2。
当n ≥4,(nlogn)/2-n/2≥(nlogn)/4,故可得∀n ≥4,log(n!) ≥(nlogn)/4,即log(n!)= Ω(nlogn)。
算法设计与分析+习题参考答案5..证明等式gcd(m,n)=gcd(n,m mod n)对每⼀对正整数m,n都成⽴.Hint:根据除法的定义不难证明:●如果d整除u和v, 那么d⼀定能整除u±v;●如果d整除u,那么d也能够整除u的任何整数倍ku.对于任意⼀对正整数m,n,若d能整除m和n,那么d⼀定能整除n和r=m mod n=m-qn;显然,若d能整除n和r,也⼀定能整除m=r+qn和n。
数对(m,n)和(n,r)具有相同的公约数的有限⾮空集,其中也包括了最⼤公约数。
故gcd(m,n)=gcd(n,r)6.对于第⼀个数⼩于第⼆个数的⼀对数字,欧⼏⾥得算法将会如何处理?该算法在处理这种输⼊的过程中,上述情况最多会发⽣⼏次?Hint:对于任何形如0<=m并且这种交换处理只发⽣⼀次.7.a.对于所有1≤m,n≤10的输⼊, Euclid算法最少要做⼏次除法?(1次)b. 对于所有1≤m,n≤10的输⼊, Euclid算法最多要做⼏次除法?(5次)gcd(5,8)习题1.21.(农夫过河)P—农夫W—狼G—⼭⽺C—⽩菜2.(过桥问题)1,2,5,10---分别代表4个⼈, f—⼿电筒4. 对于任意实系数a,b,c, 某个算法能求⽅程ax^2+bx+c=0的实根,写出上述算法的伪代码(可以假设sqrt(x)是求平⽅根的函数)算法Quadratic(a,b,c)//求⽅程ax^2+bx+c=0的实根的算法//输⼊:实系数a,b,c//输出:实根或者⽆解信息D←b*b-4*a*cIf D>0temp←2*ax1←(-b+sqrt(D))/tempx2←(-b-sqrt(D))/tempreturn x1,x2else if D=0 return –b/(2*a)else return “no real roots”else //a=0if b≠0 return –c/belse //a=b=0if c=0 return “no real numbers”else return “no real roots”5.描述将⼗进制整数表达为⼆进制整数的标准算法a.⽤⽂字描述b.⽤伪代码描述解答:a.将⼗进制整数转换为⼆进制整数的算法输⼊:⼀个正整数n输出:正整数n相应的⼆进制数第⼀步:⽤n除以2,余数赋给Ki(i=0,1,2...),商赋给n第⼆步:如果n=0,则到第三步,否则重复第⼀步第三步:将Ki按照i从⾼到低的顺序输出b.伪代码算法DectoBin(n)//将⼗进制整数n转换为⼆进制整数的算法//输⼊:正整数n//输出:该正整数相应的⼆进制数,该数存放于数组Bin[1...n]中i=1while n!=0 do {Bin[i]=n%2;n=(int)n/2;i++;}while i!=0 do{print Bin[i];i--;}9.考虑下⾯这个算法,它求的是数组中⼤⼩相差最⼩的两个元素的差.(算法略) 对这个算法做尽可能多的改进.算法MinDistance(A[0..n-1])//输⼊:数组A[0..n-1]//输出:the smallest distance d between two of its elements习题1.31.考虑这样⼀个排序算法,该算法对于待排序的数组中的每⼀个元素,计算⽐它⼩的元素个数,然后利⽤这个信息,将各个元素放到有序数组的相应位置上去.a.应⽤该算法对列表‖60,35,81,98,14,47‖排序b.该算法稳定吗?c.该算法在位吗?解:a. 该算法对列表‖60,35,81,98,14,47‖排序的过程如下所⽰:b.该算法不稳定.⽐如对列表‖2,2*‖排序c.该算法不在位.额外空间for S and Count[]4.(古⽼的七桥问题)习题1.41.请分别描述⼀下应该如何实现下列对数组的操作,使得操作时间不依赖数组的长度. a.删除数组的第i 个元素(1<=i<=n)b.删除有序数组的第i 个元素(依然有序) hints:a. Replace the i th element with the last element and decrease the array size of 1b. Replace the ith element with a special symbol that cannot be a value of the array ’s element(e.g., 0 for an array of positive numbers ) to mark the i th position is empty. (―lazy deletion ‖)第2章习题2.17.对下列断⾔进⾏证明:(如果是错误的,请举例) a. 如果t(n )∈O(g(n),则g(n)∈Ω(t(n)) b.α>0时,Θ(αg(n))= Θ(g(n)) 解:a. 这个断⾔是正确的。
算法第四版习题答案1.2/** 1.2.1 编写一个Point2D的用例,从命令行接受一个整数N。
在单位正方形内生成N个随机点,然后计算两点之间的最近距离*/public class testPoint2D {public testPoint2D() {// TODO Auto-generated constructor stub}public static void drawbox(double bw, double bh){StdDraw.setPenRadius(0.005);StdDraw.setPenColor(StdDraw.RED);Interval1D xinterval = new Interval1D(0, bw);Interval1D yinterval = new Interval1D(0, bh);Interval2D box = new Interval2D(xinterval, yinterval);box.draw();}public static Point2D[] drawpoint(int N){Point2D[] p=new Point2D[N];for(int i=0;i<N;i++){double x=Math.random();double y=Math.random();p[i]=new Point2D(x, y) ;p[i].draw();}return p;}public static double findmindist(Point2D[] p){Point2D p1=p[0];Point2D p2=p[1];double mindist =p[0].distanceTo(p[1]);StdDraw.setPenRadius(0.002);StdDraw.setPenColor(StdDraw.RED);int n=p.length ;for(int i=1;i<n-1;i++)for(int j=i+1;j<n;j++){double temp=p[i].distanceTo(p[j]);if(temp<mindist){ mindist=temp;p1=p[i];p2=p[j];}}p1.drawTo(p2);StdOut.print("min dist="+mindist +p1.toString()+p2.toString());return mindist;}public static void main(String[] args) {int N=StdIn.readInt();//读取画点的数量//StdDraw.setXscale(0,1 );//StdDraw.setYscale(0,1);drawbox(1,1);//画出一个单位大小的正方形StdDraw.setPenRadius(0.01);StdDraw.setPenColor(StdDraw.BLACK);//drawpoint(N);//画出N个点double min=findmindist(drawpoint(N));}}/** 编写一个Interval1D的用例,从命令行接受一个整数N。
计算机算法设计与分析第四版课后答案【篇一:计算机算法分析与设计(第四版)习题算法分析部分详解(实验六)】//6-1、6-6项目vc++6.0测试通过//6-15项目vc2005测试通过//6-1 最小长度电路板排列问题//头文件stdafx.h// stdafx.h : include file for standard system include files,// or project specific include files that are used frequently, but // are changed infrequently//#pragma once#define win32_lean_and_mean // exclude rarely-used stuff from windows headers #include stdio.h#include tchar.h// todo: reference additional headers your program requires here// sy61.cpp : defines the entry point for the console application.////description://分支限界法 6_1 最小长度电路板排列问题//#include my.h#include stdafx.h#include iostream#include queueusing namespace std;int n,m;//#include outofbounds.h//定义节点类class boardnode{friend int fifoboards(int **,int ,int,int *);//非类成员,可以访问私有成员的函数,最优序列查找public:operator int() const{return cd;}//返回常数 cdint len();public:int *x,s,cd,*low,*high;//x表示当前节点的电路板排列,s表示当前节点排列好的电路板的数//表示当前节点的最大长度,low,high分别表当前节点表示每一个连接块的第一个,和最后一个电路板//的位置};//编写类的len()函数,求出当前节点的连接块长度的最大值int boardnode::len(){int tmp=0;for(int k=1;k=m;k++)if(low[k]=n high[k]0 tmphigh[k]-low[k])tmp=high[k]-low[k];return tmp;}int fifioboards(int **b,int n,int m,int *bestx)//n为电路板的数量,m为连接块的数量 {// int bestd;queueboardnode q;//声明boardnode类的节点队列qboardnode e;e.x=new int[n+1];//为数组指针x分配n+1个动态空间,存储当前的排列e.s=0;//最初时,排列好的电路板的数目为0e.cd=0;e.low=new int[m+1];//存储每个连接块的第一个电路板的位置e.high=new int[m+1];//存储每个连接块的最后一个电路板的位置 for(int i=1;i=m;i++){e.high[i]=0;//初始化开始时的每个连接块的最后一个电路板的位置为0,表示连接块i还没有电路板放入e.x的排列中e.low[i]=n+1;//初始化开始时的每个连接块的第一个电路板的位置为n+1,表示连接块i还没有电路板放入e.x的排列中}for(i=1;i=n;i++)e.x[i]=i;//初始化e.x的排列为1,2,3.....nint bestd=n+1;//最优距离bestx=0;//记录当前最优排列do{if(e.s==n-1)//当已排列了n-1个时{//判断是否改变每个连接块的最后一个电路板的位置for(int j=1;j=m;j++)if(b[e.x[n]][j] ne.high[j])e.high[j]=n;int ld=e.len();//存储当前节点的各连接块长度中的最大长度//如果当前的最大长度小于了n+1if(ldbestd){delete[] bestx;bestx=e.x;bestd=ld;//最优距离}else delete[] e.x;//删除分配给e.x的数组空间delete[] e.low;//删除分配给e.low的数组空间delete[] e.high;//删除分配给e.high的数组空间}else{int curr=e.s+1;//rr记录现在应该排列第几个电路板for(int i=e.s+1;i=n;i++)//处理扩展节点下一层所有子节点{boardnode n;n.low=new int[m+1];//与if中的意思相同n.high=new int[m+1];for(int j=1;j=m;j++){n.low[j]=e.low[j];//将e.low[]中的值赋给n.low[]n.high[j]=e.high[j];if(b[e.x[i]][j]){if(currn.low[j])n.low[j]=curr;//若当前节点连接块j的第一个电路板的位置比现在正在排列的电路板的位置还小if(currn.high[j])n.high[j]=curr;}}n.cd=n.len();//如果,当前节点的最大长度小于了最优长度则:if(n.cdbestd){n.x=new int[n+1];n.s=e.s+1;for(int j=1;j=n;j++)n.x[j]=e.x[j];n.x[n.s]=e.x[i];//交换位置n.x[i]=e.x[n.s];//交换位置q.push(n);//将节点n加入队列中}else{delete[] n.low;delete[] n.high;}//printf(%d,bestd);}delete[] e.x;//当前扩展节点所有子节点均考虑,变成死结点} //try{if(!q.empty()){e=q.front(); //取队列首节点作为扩展节点q.pop();}else return bestd;//}//catch(outofbounds)//{//return bestd;//}//printf(finish);}while(!q.empty());return bestd;return 1;}//测试void main(){//scanf(%d%d,n,m);cinnm;int **b=new int*[n+1];for (int t=0; t=n; t++)b[t] = new int[m+1];for(int i=1;i=n;i++)for(int j=1;j=m;j++)cinb[i][j];//scanf(%d,b[i][j]);int *bestx=new int[n+1];int bestd=0;bestd=fifioboards(b,n,m,bestx);printf(%d\n,bestd);for(i=1;i=n;i++){coutbestx[i] ;}coutendl;}//6-6 经典n皇后问题//description:经典n皇后问题广度优先建议n=14解空间为子集树 //参考答案说排列树是不正确的,本例打印n*n棋盘的所有解,即放置方法 #include iostream#include fstream#include algorithm#include functional#include queueusing namespace std;//本例子直接输入棋盘大小,不用文件//ifstream in(input.txt); //请在项目文件夹下新建一个input.txt//ofstream out(output.txt);class node{public:node(int n){t = 0;this-n = n;loc = new int[n + 1];for (int i = 0; i= n; ++i){loc[i] = 0;}}node(const node other){this-t = other.t;this-n = other.n;this-loc = new int [n + 1];for (int i = 0; i = n; ++i){this-loc[i] = other.loc[i];}}int t;//已放置t个皇后【篇二:计算机算法分析与设计(第四版)习题算法分析部分详解(实验二)】>实验内容:算法实现问题2-1、2-5、2-7//2-1 众数问题思路1:先排序,然后再统计,时间复杂度较高。
【关键字】分析《算法分析与设计》作业参考答案作业一一、名词解释:1.递归算法:直接或间接地调用自身的算法称为递归算法。
2.程序:程序是算法用某种程序设计语言的具体实现。
2、简答题:1.算法需要满足哪些性质?简述之。
算法是若干指令的有穷序列,满足性质:1)输入:有零个或多个外部量作为算法的输入。
2)输出:算法产生至少一个量作为输出。
3)确定性:组成算法的每条指令清晰、无歧义。
4)有限性:算法中每条指令的执行次数有限,执行每条指令的时间也有限。
2.简要分析分治法能解决的问题具有的特征。
分析分治法能解决的问题主要具有如下特征:1)该问题的规模缩小到一定的程度就可以容易地解决;2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;3)利用该问题分解出的子问题的解可以合并为该问题的解;4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
3.简要分析在递归算法中消除递归调用,将递归算法转化为非递归算法的方法。
将递归算法转化为非递归算法的方法主要有:1)采用一个用户定义的栈来模拟系统的递归调用工作栈。
该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。
2)用递推来实现递归函数。
3)通过Cooper变换、反演变换能将一些递归转化为尾递归,从而迭代求出结果。
后两种方法在时空复杂度上均有较大改善,但其适用范围有限。
三、算法编写及算法应用分析题:1.冒泡排序算法的基本运算如下:for i ←1 to n-1 dofor j ←1 to n-i doif a[j]<a[j+1] then交换a[j]、a[j+1];分析该算法的时间复杂性。
解答:排序算法的基本运算步为元素比较,冒泡排序算法的时间复杂性就是求比较次数与n的关系。
1)设比较一次花时间1;2)内循环次数为:n-i次,(i=1,…n),花时间为:3)外循环次数为:n-1,花时间为:2.设计一个分治算法计算一棵二叉树的高度。
实验六分支限界法//6-1、6-6 项目VC++6.0 测试通过//6-15 项目VC2005 测试通过//6-1 最小长度电路板排列问题//头文件stdafx.h// stdafx.h : include file for standard system include files,// or project specific include files that are used frequently, but// are changed infrequently// #pragma once// Exclude rarely-used stuff from Windows headers#define WIN32_LEAN_AND_MEAN#include <stdio.h>#include <tchar.h>// TODO: reference additional headers your program requires here// sy61.cpp : Defines the entry point for the console application. ////Description://分支限界法6_1 最小长度电路板排列问题//#include "my.h"#include "stdafx.h"#include <iostream>#include <queue> using namespace std;int n,m;//#include "OutOfBounds.h" //定义节点类class BoardNode{friend int FIFOBoards(int **,int ,int,int *&);// 非类成员,可以访问私有成员的函数,最优序列查找public:operator int() const{return cd;}// 返回常数cdint len();public:int *x,s,cd,*low,*high;//x 表示当前节点的电路板排列,s 表示当前节点排列好的电路板的数//表示当前节点的最大长度,low ,high 分别表当前节点表示每一个连接块的第一个,和最后一个电路板//的位置};〃编写类的len()函数,求出当前节点的连接块长度的最大值int BoardNode::len(){int tmp=0;for(int k=1;k<=m;k++)if(low[k]<=n && high[k]>0 && tmp<high[k]-low[k]) tmp=high[k]-low[k];return tmp;}int FIFIOBoards(int **B ,int n ,int m ,int *&bestx)//n 为电路板的数量, m 为连接块的数量 {// int bestd;queue<BoardNode> q;//声明 BoardNode 类的节点队列 q BoardNode E;E.x=new int[n+1];// 为数组指针 x 分配 n+1 个动态空间,存储当前的排列E.s=0;//最初时,排列好的电路板的数目为0 E.cd=0;E.low=new int[m+1];// 存储每个连接块的第一个电路板的位置 E.high=new int[m+1];// 存储每个连接块的最后一个电路板的位置 for(int i=1;i<=m;i++){E.high[i]=0;// 初始化开始时的每个连接块的最后一个电路板的位置为 块 i 还没有电路板放入 E.x 的排列中E.low[i]=n+1;// 初始化开始时的每个连接块的第一个电路板的位置为 接块 i 还没有电路板放入 E.x 的排列中}for(i=1;i<=n;i++)E.x[i]=i;// 初始化 E.x 的排列为 1, 2,3 nint bestd=n+1;// 最优距离 bestx=O;//记录当前最优排列do{if(E.s==n-1)// 当已排列了 n-1 个时{ //判断是否改变每个连接块的最后一个电路板的位置 for(int j=1;j<=m;j++)if(B[E.x[n]][j] && n>E.high[j]) E.high[j]=n;int ld=E.len();// 存储当前节点的各连接块长度中的最大长度 //如果当前的最大长度小于了 n+1if(ld<bestd){delete[] bestx; bestx=E.x;bestd=ld;//最优距离}else delete[] E.x;//删除分配给 E.x 的数组空间 delete[] E.low;// 删除分配给E.low 的数组空间 delete[] E.high;// 删除分配给 E.high 的数组空间}else{int curr=E.s+1;//rr 记录现在应该排列第几个电路板 for(int i=E.s+1;i<=n;i++)//处理扩展节点下一层所有子节点 {0,表示连接n+1,表示连BoardNode N;N.low=new int[m+1];// 与if 中的意思相同N.high=new int[m+1];for(int j=1;j<=m;j++){N.low[j]=E.low[j];// 将 E.low[] 中的值赋给N.low[]N.high[j]=E.high[j];if(B[E.x[i]][j]){if(curr<N.low[j])N.low[j]=curr;// 若当前节点连接块j 的第一个电路板的位置比现在正在排列的电路板的位置还小if(curr>N.high[j])N.high[j]=curr;}}N.cd=N.len();//如果,当前节点的最大长度小于了最优长度则:if(N.cd<bestd){N.x=new int[n+1];N.s=E.s+1;for(int j=1;j<=n;j++)N.x[j]=E.x[j];N.x[N.s]=E.x[i];// 交换位置N.x[i]=E.x[N.s];// 交换位置q.push(N);// 将节点N 加入队列中}else{delete[] N.low;delete[] N.high;}//printf("%d",bestd);}delete[] E.x;// 当前扩展节点所有子节点均考虑,变成死结点}//try{ if(!q.empty()){E=q.front(); //取队列首节点作为扩展节点q.pop();}else return bestd;//}//catch(OutOfBounds)//{//return bestd;//}//printf("finish");}while(!q.empty()); return bestd;return 1;}//测试void main() {//scanf("%d%d",&n,&m); cin>>n>>m;int **B=new int*[n+1];for (int t=0; t<=n; t++)B[t] = new int[m+1]; for(inti=1;i<=n;i++) for(intj=1;j<=m;j++) cin>>B[i][j];//scanf("%d",&B[i][j]);int *bestx=new int[n+1]; int bestd=0; bestd=FIFIOBoards(B,n,m,bestx);printf("%d\n",bestd); for(i=1;i<=n;i++){ cout<<bestx[i]<<"} cout<<endl;}//6-6 经典n 皇后问题H.//Description: 经典n 皇后问题广度优先建议n<=14 解空间为子集树//参考答案说排列树是不正确的,本例打印n*n 棋盘的所有解,即放置方法#include <iostream>#include <fstream> #include <algorithm>#include <functional>#include <queue> using namespace std;//本例子直接输入棋盘大小,不用文件//ifstream in("input.txt"); // 请在项目文件夹下新建一个input.txt //ofstreamout("output.txt");class Node{public:Node(int n){t = 0; this->n = n;loc = new int[n + 1];for (int i = 0; i<= n; ++i){loc[i] = 0;}}Node(const Node &other){ this->t = other.t;this->n = other.n; this->loc = new int [n + 1]; for (int i = 0; i <= n;++i){ this->loc[i] = other.loc[i];}}int t;// 已放置t 个皇后int *loc;//loc[1:t] int n;// 共放置n 个皇后bool checkNext(int next); void printQ();};bool Node::checkNext(int next){int i;for (i = 1; i <= t; ++i){if (loc[i] == next)// 检测同列{ return false;}if (loc[i] - next == t + 1 - i)// 检测反斜线行差== 列差{return false;}if (loc[i] - next == i - t - 1)// 检测正斜线{ return false;}} return true;}void Node::printQ(){for (int i = 1; i <= n; ++i){ cout<<loc[i]<<" ";} cout<<endl;}class Queen{ public:int n;//n 皇后int ansNum;// 对于n 皇后解的个数Queen(int n){ this->n = n; ansNum = 0;}void ArrangQueen();};void Queen::ArrangQueen(){ queue<Node> Q; Node ini(n); // 初始化Q.push(ini); while(!Q.empty()){Node father = Q.front(); //取队列下一个节点Q.pop();if (father.t == n){father.printQ();++ansNum;}for (int i = 1; i <= n; ++i) //一次性将当前扩展节点所有子节点考虑完,符合条件的插入队列if (father.checkNext(i)){Node Child(father); ++Child.t;Child.loc[Child.t] = i; Q.push(Child);}}}}int main(){//#define in cin//#define out cout cout<<" 请输入棋盘大小n:"; int n; cin>>n; // 从文件中读入一个整数//for(int Case = 1; Case <= cases; ++Case){ //int n; //in>>n; Queen Q(n); Q.ArrangQueen();//out<<"Case #"<<Case<<": "<<Q.ansNum<<endl;cout<<" 共"<<Q.ansNum<<" 种放置皇后方法,如上所示。