c语言:用栈实现F(n)=n*F(n-1),当n=1时,F(n)=1
答案:2 悬赏:70
解决时间 2021-12-29 20:44
- 提问者网友:长安小才冯
- 2021-12-29 15:48
求给出具体程序,我实在不懂返回地址是什么意思,入栈和出站用push(s,x)和pop(s)代表
最佳答案
- 二级知识专家网友:眠于流年
- 2021-12-29 16:09
这是递归 求阶层
函数调用 都 运用 到了 堆栈,阶层递归函数也是这样,
返回的 是 函数的地址。
函数调用 都 运用 到了 堆栈,阶层递归函数也是这样,
返回的 是 函数的地址。
全部回答
- 1楼网友:兮沫♡晨曦
- 2021-12-29 16:40
【程序】 # include int delta_i[ ]={2,1,-1,-2,-2,-1,1,2}; int delta_j[ ]={1,2,2,1,-1,-2,-2,-1}; int board[8][8]; int exitn(int i,int j,int s,int a[ ]) { int i1,j1,k,count; for (count=k=0;k<8;k++) { i1=i+delta_i[(s+k)%8]; j1=i+delta_j[(s+k)%8]; if (i1>=0&&i1<8&&j1>=0&&j1<8&&board[i1][j1]==0) a[count++]=(s+k)%8; } return count; } int next(int i,int j,int s) { int m,k,mm,min,a[8],b[8],temp; m=exitn(i,j,s,a); if (m==0) return –1; for (min=9,k=0;k { temp=exitn(i+delta_i[a[k]],j+delta_j[a[k]],s,b); if (temp { min=temp; kk=a[k]; } } return kk; } void main() { int sx,sy,i,j,step,no,start; for (sx=0;sx<8;sx++) for (sy=0;sy<8;sy++) { start=0; do { for (i=0;i<8;i++) for (j=0;j<8;j++) board[j]=0; board[sx][sy]=1; i=sx; j=sy; for (step=2;step<64;step++) { if ((no=next(i,j,start))==-1) break; i+=delta_i[no]; j+=delta_j[no]; board[j]=step; } if (step>64) break; start++; } while(step<=64) for (i=0;i<8;i++) { for (j=0;j<8;j++) printf(“%4d”,board[j]); printf(“\n\n”); } scanf(“%*c”); } } 七、分治法【问题】 大整数乘法 问题描述: 通常,在分析一个算法的计算复杂性时,都将加法和乘法运算当作是基本运算来处理,即将执行一次加法或乘法运 算所需的计算时间当作一个仅取决于计算机硬件处理速度的常数。 这个假定仅在计算机硬件能对参加运算的整数直接表示和处理时才是合理的。然而,在某些情况下,我们要处理很 大的整数,它无法在计算机硬件能直接表示的范围内进行处理。若用浮点数来表示它,则只能近似地表示它的大小 ,计算结果中的有效数字也受到限制。若要精确地表示大整数并在计算结果中要求精确地得到所有位数上的数字, 就必须用软件的方法来实现大整数的算术运算。 请设计一个有效的算法,可以进行两个n位大整数的乘法运算。 设x和y都是n位的二进制整数,现在要计算它们的乘积xy。我们可以用小学所学的方法来设计一个计算乘积xy的算 法,但是这样做计算步骤太多,显得效率较低。如果将每2个1位数的乘法或加法看作一步运算,那么这种方法要作 o(n2)步运算才能求出乘积xy。下面我们用分治法来设计一个更有效的大整数乘积算法。 图6-3 大整数x和y的分段 我们将n位的二进制整数x和y各分为2段,每段的长为n/2位(为简单起见,假设n是2的幂),如图6-3所示。 由此,x=a2n/2+b,y=c2n/2+d。这样,x和y的乘积为: xy=(a2n/2+b)(c2n/2+d)=ac2n+(ad+cb)2n/2+bd (1) 如果按式(1)计算xy,则我们必须进行4次n/2位整数的乘法(ac,ad,bc和bd),以及3次不超过n位的整数加法( 分别对应于式(1)中的加号),此外还要做2次移位(分别对应于式(1)中乘2n和乘2n/2)。所有这些加法和移 位共用o(n)步运算。设t(n)是2个n位整数相乘所需的运算总数,则由式(1),我们有: (2) 由此可得t(n)=o(n2)。因此,用(1)式来计算x和y的乘积并不比小学生的方法更有效。要想改进算法的计算 复杂性,必须减少乘法次数。为此我们把xy写成另一种形式: xy=ac2n+[(a-b)(d-c)+ac+bd]2n/2+bd (3) 虽然,式(3)看起来比式(1)复杂些,但它仅需做3次n/2位整数的乘法(ac,bd和(a-b)(d-c)),6次加、 减法和2次移位。由此可得: (4) 用解递归方程的套用公式法马上可得其解为t(n)=o(nlog3)=o(n1.59)。利用式(3),并考虑到x和y的符号对结果 的影响,我们给出大整数相乘的完整算法mult如下: function mult(x,y,n); {x和y为2个小于2n的整数,返回结果为x和y的乘积xy} begin s=sign(x)*sign(y); {s为x和y的符号乘积} x=abs(x); y=abs(y); {x和y分别取绝对值} if n=1 then if (x=1)and(y=1) then return(s) else return(0) else begin a=x的左边n/2位; b=x的右边n/2位; c=y的左边n/2位; d=y的右边n/2位; ml=mult(a,c,n/2); m2=mult(a-b,d-c,n/2); m3=mult(b,d,n/2); s=s*(m1*2n+(m1+m2+m3)*2n/2+m3); return(s); end; end; 上述二进制大整数乘法同样可应用于十进制大整数的乘法以提高乘法的效率减少乘法次数。 【问题】 最接近点对问题 问题描述: 在应用中,常用诸如点、圆等简单的几何对象代表现实世界中的实体。在涉及这些几何对象的问题中,常需要了解 其邻域中其他几何对象的信息。例如,在空中交通控制问题中,若将飞机作为空间中移动的一个点来看待,则具有 最大碰撞危险的2架飞机,就是这个空间中最接近的一对点。这类问题是计算几何学中研究的基本问题之一。下面 我们着重考虑平面上的最接近点对问题。 最接近点对问题的提法是:给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小。 严格地说,最接近点对可能多于1对。为了简单起见,这里只限于找其中的一对。 这个问题很容易理解,似乎也不难解决。我们只要将每一点与其他n-1个点的距离算出,找出达到最小距离的两个 点即可。然而,这样做效率太低,需要o(n2)的计算时间。我们能否找到问题的一个o (nlogn)算法。 这个问题显然满足分治法的第一个和第二个适用条件,我们考虑将所给的平面上n个点的集合s分成2个子集s1和s2 ,每个子集中约有n/2个点,然后在每个子集中递归地求其最接近的点对。在这里,一个关键的问题是如何实现分 治法中的合并步骤,即由s1和s2的最接近点对,如何求得原集合s中的最接近点对,因为 s1和s2的最接近点对未必 就是s的最接近点对。如果组成s的最接近点对的2个点都在s1中或都在s2中,则问题很容易解决。但是,如果这2个 点分别在 s1和s2中,则对于s1中任一点p,s2中最多只有n/2个点与它构成最接近点对的候选者,仍需做n2/4次计 算和比较才能确定s的最接近点对。因此,依此思路,合并步骤耗时为o(n2)。整个算法所需计算时间t(n)应满足: t(n)=2t(n/2)+o(n2) 它的解为t(n)=o(n2),即与合并步骤的耗时同阶,显示不出比用穷举的方法好。从解递归方程的套用公式法,我们 所有点
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯