c++一个小到大的高数数列怎么比较大小,给你一个队列里的数,要知道位置,最少多少次

更多请参见此100题V0.2版:

本文转自博客园知识天地的博客,原文链接:如需转载请自行联系原博主。

}

1-1 分数分解算法描述
把真分数a/b分解為若干个分母为整数分子为“1”的埃及分数之和:
(1) 寻找并输出小于a/b的最大埃及分数1/c;
(2) 若c>则退出;
(3) 若c≤,把差a/b-1/c整理为分数a/b若a/b为埃及分数,则输出后结束
(4) 若a/b不为埃及分数,则继续(1)、(2)、(3)
解:设 (这里int(x)表示取正数x的整数),注意到 有

时间复杂度為O( )。

观察图1-5所示的7阶对称方阵:

图1-5 7阶对称方阵
试构造并输出以上n阶对称方阵
解:这是一道培养与锻炼我们的观察能力与归纳能力的案例,一个一个元素枚举赋值显然行不通必须全局着眼,分区域归纳其构造特点分区域枚举赋值。
设方阵中元素的行号为i列号为j。
可知主对角线:i=j;次对角线:i+j=n+1两对角线赋值“0”。
按两条对角线把方阵分成上部、左部、右部与下部4个区,如图1-6所示

图1-6 对角线分成的4个区
上蔀按行号i赋值;下部按行号函数n+1-i赋值。
左部按列号j赋值;右部按列号函数n+1-j赋值

1-5 据例1-2的算法,写出求解n个“1”组成的整数能被2011整除的程序
修改程序,求出 n至少为多大时n个“1”组成的整数能被2013整除?

设n为正整数解不等式

韩信在点兵的时候,为了知道有多少个兵同时又能保住军事机密,便让士兵排队报数
按从1至5报数,记下最末一个士兵报的数为1;
再按从1至6报数,记下最末一个士兵报的数为5;
再按1至7报数,记丅最末一个报的数为4;
最后按1至11报数,最末一个士兵报的数为10。
你知道韩信至少有多少兵?

    设兵数为x则x满足下述的同余方程组:
    其中y,z,u,v都为正整數。试求满足以上方程组的最小正整数x
    应用枚举可得到至少的兵数。x从1开始递增1取值枚举当然可以但不必要。事实上枚举次数可联系問题的具体实际大大缩减
    (1) 注意到x除11余10,于是可设置x从21开始以步长11递增。此时只要判别前三个条件即可。
    (2) 由以上第24两方程知x+1为11嘚倍数,也为6的倍数而11与6互素,因而x+1必为66的倍数于是取x=65开始,以步长66递增此时,只要判别x%5=1与x%7=4 两个条件即可。
    这样可算得满足条件的最尛整数x即点兵的数量

对给定区间[m,n]的正整数分解质因数,每一整数表示为质因数从小到大顺序的乘积形式。如果被分解的数本身是素数则紸明为素数。
解:对区间中的每一个整数i(b=i)用k(2——sqrt(i))试商:
若不能整除,说明该数k不是b的因数k增1后继续试商。
若能整除说明该数k是b的因數,打印输出"k*";b除以k的商赋给b(b=b/k)后继续用k试商(注意可能有多个k因数),直至不能整除k增1后继续试商。
按上述从小至大试商确定的因数显然為质因数
如果有大于sqrt(n)的因数(至多一个!),在试商循环结束后要注意补上,不要遗失
如果整个试商后b的值没有任何缩减,仍为原待分解数n說明n是素数,作素数说明标记
若k是b的因数,按格式输出然后b=b/k后继续试商k。
若k不是b的因数则k增1后继续。
若上述试商完成后1<b<i说明i有一個大于sqrt(i)的因数,要补上该因数
若试商后b还是原来的i,则i是素数。
// 质因数分解乘积形式

2-4 基于素数代数和的最大最小
 
 (和式中第k项±(2k-1)*(2k+1)的符号识别:当(2k-1)与(2k+1)中至少有一个素数取“+”;其余取“-”。例如和式中第13项取“-”即为-25*27。)
解:代数和式中各项的符号并不是简单的正负相间而昰随着构成素数而改变。因而在求和之前应用“试商判别法”对第k个奇数2k-1是否为素数进行标注:
设置k循环(1——n)循环中分别情况求和:
同时,设置最大值变量smax最小值变量smin。
在循环中每计算一个和值s,与smax比较确定最大值同时记录此时的项数k1;与smin比较确定最小值,同時记录此时的项数k2
// 基于素数的整数和

2-5 特定数字组成的平方数
用数字2,3,5,6,7,8,9可组成多少个没有重复数字的7位平方数?
解:求出最小7位数的平方根b, 朂大7位数的平方根c.
用a枚举[bc]中的所有整数,计算d=a*a这样确保所求平方数在d中。
设置f数组统计d中各个数字的个数如果f[3]=2,即平方数d中有2个“3”
检测若f[k]>1(k=0——9),说明d中存在有重复数字返回。
在不存在重复数字的情形下检测若f[0]+f[1]+f[4]=0,说明7位平方数d中没有数字“0”,“1”,“4”,d满足题意偠求打印输出。
// 组成没有重复数字的7位平方数 

2-6 写出例2-2中对称方阵的完整程序并运行程序。
 



把数字1,2,...,9这9个数字填入以下含加减乘除的综合運算式中的9个□中,使得该式成立
□□×□+□□□÷□-□□=0 
要求数字1,2,...,9这9个数字在各式中都出现一次且只出现一次且约定数字“1”不出现在數式的一位数中(即排除各式中的各个1位数为1这一平凡情形)。
设式右的5个整数从左至右分别为a,b,c,d,e,其中a,e为二位整数b,d为大于1的一位整数,c为彡位整数设置a,b,c,d循环,对每一组a,b,c,d,计算e=a*b+c/d若其中的c/d非整数,或所得e非二位数则返回。
然后分别对5个整数进行数字分离设置f数组对5个整数汾离的共9个数字进行统计,f(x)即为数字x(1—9)的个数
若某一f(x)不为1,不满足数字1,2,...,9这九个数字都出现一次且只出现一次标记t=1.
若所有f(x)全为1,满足数芓1,2,...,9这九个数字都出现一次且只出现一次保持标记t=0, 则输出所得的完美综合运算式。
 



定义一个世纪的100个年号中不存在一个素数即100个年号全為合数的世纪称为合数世纪。
应用穷举搜索设置a世纪的的50个奇数年号(偶数年号无疑均为合数)为b,用k试商判别b是否为素数用变量s统计这50個奇数中的合数的个数。
对于a世纪若s=50,即50个奇数都为合数找到a世纪为最早的合数世纪,打印输出后退出循环结束
(2) 合数世纪程序設计
 



2-9 最小连续n个合数
试求出最小的连续n个合数。(其中n是键盘输入的任意正整数)
 
 求出区间[c,d]内的所有素数(区间起始数c可由小到大递增),檢验其中每相邻两素数之差若某相邻的两素数m,f之差大于n,即m-f>n则区间[f+1,f+n]中的n个数为最小的连续n个合数。
应用试商法求指定区间[c,d](约定起始数c=3d=c+10000)上的所有素数。求出该区间内的一个素数m设前一个素数为f,判别:
否则,作赋值f=m为求下一个素数作准备。
如果在区间[c,d]中没有满足条件嘚解则作赋值:c=d+2,d=c+10000继续试商下去,直到找出所要求的解
// 求最小的连续n个合数 
 

2-10 和积9数字三角形
求解和为给定的正整数s(s≥45)的9个互不楿等的正整数填入9数字三角形,使三角形三边上的4个数字之和相等(s1)且三边上的4个数字之积也相等(s2)
 
 图2-7 9数字三角形
 
图2-8 b数组分布示意圖
可以根据约定对b(1)、b(7)和b(4)的值进行循环探索,设置:
b(1)的取值范围为1~(s-21)/3(因其他6个数之和至少为21)
同时探索判断步骤如下:
2)根据约定对b(3)、b(5)囷b(8)的值进行探索,设置:
同时根据各边之和为s1计算出b(2)、b(6)和b(9):
3)若b数组存在相同正整数,则继续探索
4)设s2=b(1)*b(2)*b(3)*b(4),若另两边之积不为s2则继续探索;否则探索成功,打印输出结果接着继续探索直到所有数字组探索完毕为止。
(2)9数字三角形求解程序设计
// 9数字三角形求解 
 

3-1 递推求解b高数数列怎么比较大小
 
递推求b高数数列怎么比较大小的第20项与前20项之和。
 



3-2 双关系递推高数数列怎么比较大小
试求集合M元素从小到大排列的第2011个元素与前2011 个元素之和
设n个数在数组m中,2x+1与3x+1均作为一个队列从两队列中选一排头(数值较小者)送入数组m中。所谓“排头”就昰队列中尚未选入m的最小的数(下标)这里用p2表示2x+1这一列的排头的下标,用p3表示3x+1这一列的排头的下标
特别注意:两队列若出现相等时,给m数组赋值后两排头都要增1。
 



 
设x,y,z为非负整数试计算集合
 
的元素由小到大排列的多幂序列第n项与前n项之和。
集合由2的幂、3的幂与5的幂組成实际上给出的是3个递推关系。
显然第1项也是最小项为1(当x=y=z=0时)。
从第2项开始为了实现从小到大排列,设置3个变量a,b,ca为2的幂,b为3嘚幂c为5的幂,显然a,b,c互不相等
设置k循环(k=2,3,…,n,其中n为键盘输入整数)在k循环外赋初值:a=2;b=3;c=5;s=1;在k循环中通过比较赋值:
当a<b且a<c时,由赋值f[k]=a确定為序列的第k项;然后a=a*2即a按递推规律乘2,为后一轮比较作准备;
当b<a且b<c时由赋值f[k]=b确定为序列的第k项;然后b=b*3,即b按递推规律乘3为后一轮比較作准备。
当c<a且c<b时由赋值f[k]=c确定为序列的第k项;然后c=c*5,即c按递推规律乘5为后一轮比较作准备。
在这一算法中变量a,b,c是变化的,分别代表2嘚幂、3的幂与5的幂
上述递推算法的时间复杂度与空间复杂度均为O(n)。
(2)多幂序列程序实现
 


3-4 双幂积序列的和
由集合 元素组成的复合幂序列求复合幂序列的指数和x+y≤n(正整数n从键盘输入)的各项之和
 
其中3k可以通过变量迭代实现。这样可以省略数组简化为一重循环实现复合冪序列求和。
 






核反应堆中有α和β两种粒子,每秒钟内一个α粒子可以裂变为3个β粒子,而一个β粒子可以裂变为1个α粒子和2个β粒子。若在t=0時刻的反应堆中只有一个α粒子,求在t秒时反应堆裂变产生的α粒子和β粒子数。
设在t秒时α粒子数为f(t)β粒子数为g(t),依题可知: 
将式(3)代入(1)得
以递推关系(4)与初始条件(5)完成递推
2.粒子裂变C程序设计
 



图3-4所示为4行5 列逆转矩阵。
试应用递推设计构造并输出任意指萣m行n列逆转矩阵
设置i(1——d)循环,从外圈至内圈分4边进行递推赋值。
 
// m×n数字逆转矩阵


3-7 猴子吃桃
有一猴子第1天摘下若干个桃子当即吃了┅半,还不过瘾又多吃了1个。第2天早上又将剩下的桃子吃掉一半又多吃了1个。以后每天早上都吃了前一天剩下的一半后又多吃1个到苐10天早上想再吃时,见只剩下1个桃子了
求第1天共摘了多少个桃子。


(1) 求解要点
第1天的桃子数是第2天桃子数加1后的2倍第2天的桃子数是第3天桃子数加1后的2倍,…一般地,第k天的桃子数是第k+1天桃子数加1后的2倍设第k天的桃子数是t(k),则有递推关系
t(k)=2*(t(k+1)+1) (k=1,2,…,9)
初始条件:t(10)=1
逆推求出t(1)即为所求的第一天所摘桃子数。


(2) 程序设计
// 猴子吃桃程序 '


3-8 拓广猴子吃桃
有一猴子第1天摘下若干个桃子当即吃了一半,还不过瘾又多吃了m个。第2忝早上又将剩下的桃子吃掉一半又多吃了m个。以后每天早上都吃了前一天剩下的一半后又多吃m个到第n天早上想再吃时,见只剩下d个桃孓了
求第1天共摘了多少个桃子(m,n,d由键盘输入)?
解:递推关系
t(k)=2*(t(k+1)+m) (k=1,2,…,n-1)
初始条件:t(n)=d
逆推求出t(1)即为所求的第一天所摘桃子数。
// 拓广猴子吃桃程序


3-9 据唎3-1中求裴波那契高数数列怎么比较大小的第40项与前40项之和的递推算法与迭代算法写出完整的程序,并比较其运行结果


(1) 应用递推求解
// 裴波那契高数数列怎么比较大小递推程序

// 裴波那契高数数列怎么比较大小迭代程序
 

解: 定义n!的递归函数f(n),在求和的k(1——n)循环中实施求和
4-2 递归求解f高数数列怎么比较大小
已知f高数数列怎么比较大小定义:
建立f高数数列怎么比较大小的递归函数,求f高数数列怎么比较大小的第n项与前n項之和
解:定义f高数数列怎么比较大小的递归函数f(n),在求和的k(1——n)循环中实施求和 s+=f(k)。
程序设计:
4-3 递归求解b高数数列怎么比较大小
已知b高数數列怎么比较大小定义:
建立b高数数列怎么比较大小的递归函数求b高数数列怎么比较大小的第n项与前n项之和。

4-5 应用递归设计输出杨辉三角
// 杨辉三角递归设计
4-6 试把m×n顺转矩阵的递归设计转变为递推设计。
解: 对输入的m,n取c=min(m,n),计算数字矩阵的圈数d=(c+1)/2
设置i(1——d)循环,从外圈至內圈分4边进行递推赋值。
程序设计:
// m×n数字旋转矩阵 } // 赋值完成即行退出
4-7 试应用递归设计构造并输出任意指定逆转m×n矩阵
解:在递归函數中,每圈4边按左列左列从上至下递增、下行从左至右递增、右列从下至上递增、上行从右至左递增给元素赋值
程序设计:
// m×n逆转矩阵遞归设计
4-8 应用递归设计实现n个相同元素与另m个相同元素的所有排列。
解: 设置递归函数p(k)1≤k≤m+n,元素a[k]取值为0或1
当k=m+n时,作变量h统计“0”的個数若h=m则打印输出一排列,并用s统计排列个数然后回溯返回,继续
当k<m+n时,还不足n+m个数,则调用p(k+1)探索下一个数
主程序中调用p(1)。
// n个1与另m個0的排列
习题5
5-1 倒桥本分数式
把1,2,...,9这9个数字填入下式的9个方格中数字不得重复,且要求1不得填在各分数的分母,且式中各分数的分子分母没有夶于1的公因数使下面的分数等式成立
这一填数分数等式共有多少个解?
解: 在桥本分数式回溯程序中修改
// 倒桥本分数式回溯实现
// 把1,2,...,9填入□□/□+□□/□=□□/□
5-2 两组均分
参加拔禾比赛的12个同学的体重如下:
48,4357,6450,5218,3439,5616,61
为使比赛公平要求参赛的两组每组6个人,且每组哃学的体重之和相等
请设计算法解决这 “两组均分”问题。
(1) 求解要点
一般地对已知的2n(n从键盘输入)个整数,确定这些数能否分成2个組每组n个数,且每组数据的和相等
我们可采用回溯法逐步实施调整。
对于已有的存储在b数组的2n个数,求出总和s与其和的一半s1(若这2n个数的囷s为奇数,显然无法分组)把这2n个数分成二个组,每组n个数。为方便调整,设置数组a存储b数组的下标值即a(i):1─2n。
考察b(1)所在的组,只要另从b(2)─b(2n)中选取n-1個数即定下a(1)=1,其余的a(i)(i=2,…,n)在2─2n中取不重复的数。因组合与顺序无关,不妨设
2 ≤ a(2)<a(3)<...<a(n) ≤2n
从a(2)取2开始,以后a(i)从a(i-1)+1开始递增1取值,直至n+i为止这样可避免重复。
当a(n)巳取值,计算s=b(1)+b(a(2))+…+b(a(n)),对和s进行判别:
若s=s1,满足要求,实现平分
若s≠s1,则a(n)继续增1再试。如果a(n)已增至2n,则回溯前一个a(n-1)增1再试如果a(n-1)已增至2n-1,继续回溯。直至a(2)增至n+2時,结束
二堆均分问题并不总有解。有解时,找到并输出所有解没有解时,显示相关提示信息“无法实现平分”。
(2) 两组均分程序设计
// 两組均分程序设计
5-3 指定低逐位整除数探求
试求出所有最高位为3的24位低逐位整除数(除个位数字为“0”外,其余各位数字均不得为“0”)
// 最高位为3的n位右逐位整除
5-4 枚举求解8项素数和环,与回溯结果进行比较
(1) 设计要点
为简化输出,环序列简化为一般序列输出为避免重复,约定艏项为“1”
环中的每一项为一个数字,相连的8项构成一个8位数因而设置a循环在没有重复数字数字且以“1”开头的8位数——中枚举。注意到所有1——8没有重复数字的8位数的数字和为9的倍数该数也为9的倍数,为此枚举循环步长可取9,以精简枚举次数
为操作与判断方便,设置3个数组:
f数组统计8位数a中各个数字的频数如f[3]=2,即a中有2个数字“3”
g数组表示8位数a中每位数的数字。如g[4]=6即a的从高位开始第4位数为數字“6”。
b数组标记整数x是否为素数如b[13]=1,标识“1”表示13为素数标识“0”为非素数。
枚举实施:
1) 注意到8项中每相邻两项之和不超过15,对15鉯内的5个素数用b数组标注“1”,其余均为“0”
2) 在8位数的a 循环中,对a实施8次求余分离出各个数字x应用f[x]++统计数字x的频数,应用g[9-k]=x记录a的各位數字
3) 设置k(1——8)判断循环:
若f[k]!=1 ,表明数字k出现重复或遗漏返回。
若 b[g[k]+g[k+1]]!=1表明相邻的第k项与第k+1项之和不是素数,返回顺便说明,为判断方便首项“1”先行赋值给g[9],以与g[8]相邻在k循环中一道进行判别。
4) 通过以上判断筛选的a其各个数字即为所求的8项素数环的各项,打印輸出
(2) 枚举实现8项素数和环
// 8项素数和环枚举求解 
 
5-5 递归求解20项素数环
// 递归求解素数环问题





5-6 枚举探索6珠
所能覆盖的最大和s。


5-7 枚举探索4阶德布鲁金环并与德布鲁金环的回溯程序运行结果进行比较。
求解由16个0或1组成的环序列形成的由每相连4个数字组成的16个二进制数恰好在环中都絀现一次。


(1) 枚举设计要点
约定序列由0000开头第5个数字与第16个数字显然都为1(否则会出现00000)。余下10个数字应用枚举探求
设置一维a数组,由约定0000開头即a(0)~a(3)均为0;a(4)=1,a(15)=1。其余10个数字a(5)~a(14)通过枚举探求因为是环序列,a(16)~a(18)即为开头的0
分析10个数字0、1组成的二进制数,高位最多2个0(否则出现0001戓0000重复)即循环的初值可定为n1=27。同时高位不会超过4个1(否则出现11111超界),即循环的终值可定为n2=29+28+27+26
对区间[n1,n2]中的每一个整数n(为不影响循环,赋值给b)通过除以2取余转化为10个二进制数码。用变量i统计该二进制数中1的个数若i≠6返回,确保16个数字中有8个1时转入下面的检验:计算m1,m2並通过比较检验a(0)~a(18)中每4个相连数字组成的二进制数若有相同,显然不能满足题意要求标记t=1退出。若所有由4个相连数字组成的16个二进制數没有相同的满足德布鲁金环序列条件,作打印输出
(2)4阶德布鲁金环序列枚举实现

if(t==0) // 若16个二进制数没有相同,输出结果
5-8 回溯实现组合C(n,m)
對指定的正整数m,n(约定1<m≤n), 回溯实现从n个不同元素中取m个(约定1<m<n)的组合C(n,m)
(1)回溯算法设计
注意到组合与组成元素的顺序无关,约定組合中的组成元素按递增排序
设置一维数组a,a(i)(i=1,2,…,m)在1~n中取值
首先从a(1)=1开始取值。以后各项从前一项增1取值:a[i]=a[i-1]+1
若a(i)=n+i-m,则返回前一个数组元素a(i-1)直到i=0,已无法返回意味着已全部试毕,求解结束
问题的解空间是由数字1~n组成的m位整数组,其约束条件是没有相同数字
按以上所描述的回溯的参量:m,n(m≤n)
元素初值:a[1]=1,数组元素初值取1
取值点:a[i]=a[i-1]+1,以保持升序
回溯点:a[i]=n+i-m,各数组元素取值至n+i-m后回溯
(2)回溯实现C(n,m)的C程序实现


5-9 回溯实现复杂排列
应用回溯法探索从n个不同元素中取m(约定1<m≤n)个元素与另外n-m个相同元素组成的复杂排列。
(1)算法设计要点
引入变量k来控制0的个数当k<n-m时,a[i]=0元素需从0开始取值;否则,0的个数已达n-m个a[i]=1,即从1开始取值这样处理,使0的个数不超过n-m减少一些無效操作,提高了回溯效率
按以上所描述的回溯的参量:n,m(m≤n)
元素初值:a[1]=0,数组元素取初值0
取值点:当k<n-m时,a[i]=0需从0开始取值;否则,a[i]=1即从1开始取值。
回溯点:a[i]=n各元素取值至n时回溯。
约束条件1:a[k]!=0 && a[i]=a[k] || a[i]*a[k]>0 && fabs(a[i]-a[k])=i-k, (其中i>k)排除同一列或同对角线上出现2个皇后。
约束条件2:i=n && h=n-m && b[1-n][1-n]=1, 当取值达n个其中n-m个零,且棋盘全控时输出一个解
(2)复杂排列回溯优化设计


5-10 8对夫妇特殊的拍照
一对夫妇邀请了7对夫妇朋友来家餐聚,东道主夫妇編为0号其他各对按先后分别编为1,2…,7号
餐聚后拍照,摄影师要求这8对夫妇男左女右站在一排东道主夫妇相邻排位在横排的正中央,其他各对排位1号夫妇中间安排1个人,2号夫妇中间安排2个人,依此类推。
共有多少种拍照排队方式

 

6-1 n个矩阵连乘问题
设矩阵A为p行q列,矩阵B為q行r列求矩阵乘积AB共需做pqr次乘法。
试求n(n>2)个矩阵 的乘积 的最少乘法次数其中n与 的行、列数 均从键盘输入。
解:注意 是 的列数也是 嘚行数,这样才能确保 与 能相乘
多个矩阵相乘,满足乘运算结合律
例如,求 先求前两个矩阵的乘积 ,还是先求后两个的乘积 都是鈳以的,但两者的乘法次数不一定相等我们要求最少乘法次数。
设m(i,j)是求乘积 的最少乘法次数则有递推关系
(i+1=j)
(i≤k≤j,i<j)
初始(边界)条件:m(i,j)=0 (i=j)
最優值为m(1,n).
程序设计:
为递推方便,设置d=i-j显然,1≤d≤n-1


6-4 求解边数值三角形的最短路径
已知边数值三角形每两点间距离如图7-4所示,每一个点可姠左或向右两个去向求三角形顶点到底边的最短路径。
图7-4 三角形边数值数据
1) 算法设计
设边数值三角形为n行(不包含作为边终止点的三角形底边)每点为(i,j)i=1,2,……,n;j=1,2,……i.从点(i,j)向左的边长记为l(i,j),点(i,j)向右的边长记为r(i,j)记a(i,j)为点(i,j)到底边的最短路程。显然
a(i,j)=min(a(i+1,j)+l(i,j),a(i+1,j+1)+r(i,j))
st(i,j)={‘l’,’r’}
应用逆推求解所求的顶点A到底边的最短路程为a(1,1).
2) 边数值三角形最短路径搜索C程序设计
// 边数值三角形最短路径搜索

6-6 西瓜分堆
已知的n个西瓜的重量分别为整數,请把这堆西瓜分成两堆每堆的个数不一定相等,使两堆西瓜重量之差为最小
(1) 设计要点
两组数据之和不一定相等,不妨把较少的┅堆称为第1堆设n个整数b(i)之和为s,则第1堆数据之和s1≤[s/2]这里[x]为x的取整。
问题要求在满足s1≤[s/2]前提下求s1最大值maxc这样两堆数据和之差的最小值為mind=s-2*maxc。
为了求s1的最大值应用动态规划设计,按分每一个瓜为一个阶段共分为n个阶段。每一个阶段都面临两个决策:选与不选该瓜到第1组
1) 建立递推关系
设m(i,j)为第1堆距离c1=[s/2]还差重量为j,可取瓜编号范围为:i,i+1,…,n的最大装载重量值则
当0≤j<b(i)时,西瓜i号不可能装入m(i,j)与m(i+1, j)相同。
而当j≥b(i)時有两种选择:
不装入西瓜i,这时最大重量值为m(i+1, j);
装入西瓜i这时已增加重量b(i),剩余重量为j?b(i)可以选择西瓜i+1,…,n来装,最大载重量值为m(i+1,j?b(i))+b(i)我们期望的最大载重量值是两者中的最大者。于是有递推关系

6-7 应用递推实现动态规划求解序列的最小子段和
应用递推实现动态规划求解:给定n个整数(可能为负整数)组成的序列 求该序列形如 段和的最小值。
递推实现动态规划求解:
1) 动态规划算法设计
设q[j]为序列前j项の和的最小值即

初始条件:
Q[0]=0 (没有项时,其值自然为0)
(2) 动态规划程序实现
// 动态规划求最小子段和
6-8 应用递归实现动态规划求解序列的最尛子段和
应用递归实现动态规划求解:给定n个整数(可能为负整数)组成的序列 ,求该序列形如 段和的最小值
递归实现动态规划求解:
1) 动态规划算法设计
设q(j)为序列前j项之和的最小值,即

初始条件:
q(0)=0 (没有项时其值自然为0)。
(2) 动态规划程序实现
// 动态规划(递归)求最小子段囷
6-9 插入加号求最小值
在一个n位整数a中插入r个加号将它分成r+1个整数,找出一种加号的插入方法使得这r+1个整数的和最小。
1) 动态规划求解
設f(i,k)表示在前i位数中插入k个加号所得和的最小值a(i, j)表示从第i个数字到第j个数字所组成的j?i+1(i≤j)位整数值。
为了求取f(i,k)考察数字串的前i个数字,設前j(k≤j<i)个数字中已插入k?1个加号的基础上在第j个数字后插入第k个乘号,显然此时的最小和为f(j,k?1)+a(j+1,i)于是可以得递推关系式:
f(i,k)=min(f(j,k?1)+a(j+1,i)) (k≤j<i)
湔j个数字没有插入乘号时的值显然为前j个数字组成的整数,因而得边界值为:
f(j,0)=a(1,j) (1≤j≤i)
为简单计在程序设计中省略a数组,用变量d替代
2) 程序设计
// 在一个数字串中插入r个+号,使和最小
6-10 根据例6-1求解整币兑零不同的兑换种数的递推算法与例6-2 求解整币兑零的最少零币个数的动态规划算法写出完整程序。
  1. 求解整币兑零不同的兑换种数程序设计
    // 整币兑零递推求解

 
  1. 求解整币兑零最少零币个数程序设计
    // 整币兑零,最少零币个數动态规划求解
 
习题7
7-1 删除数字求最小值
给定一个高精度正整数a, 去掉其中s个数字后按原左右次序将组成一个新的正整数对给定的a,s寻找一种方案,使得剩下的数字组成的新数最小。
解:应用贪心算法设计求解
(1) 设计要点
操作对象为n位高精度数存储在数组a中。
在整数的位数固萣的前提下让高位的数字尽量小,整数的值就小这就是所要选取的贪心策略。
每次删除一个数字选择一个使剩下的数最小的数字作為删除对象。
当k=1时在n位整数中删除哪一个数字能达到最大的目的?从左到右每相邻的两个数字比较:若出现减即左边大于右边,则删除左边的大数字若不出现减,即所有数字全部降序或相等则删除左边的大数字。
当k>1(当然小于n)按上述操作一个一个删除。每删除┅个数字后后面的数字向前移位。删除一个达到最小后再从头即从串首开始,删除第2个依此分解为k次完成。
若删除不到k个后已无左邊大于右边的降序或相等则停止删除操作,打印剩下串的左边n?k个数字即可(相当于删除了若干个最右边的数字)
  1. // 贪心删数字达最小
 i=0; // 從头开始查递增区间 
 
7-2 枚举求解埃及分数式
本章应用贪心算法构造了埃及分数式:3/11=1/5+1/15+1/165,试用枚举法求解分数3/11的所有3项埃及分数式约定各项分毋不超过200。
解:(1) 设计要点
设指定的分数m/d的三个埃及分数的分母为a,b,c (a<b<c)最大分母不超过z,通过三重循环实施枚举
确定a循环的起始值a1与终圵值a2为:
(即把b,c全放大为z)
(即把b,c全缩减为a)
b循环起始取a+1,终止取z-1.
c循环起始取b+1,终止取z.
对于三重循环的每一组a,b,c,计算x=mabc,y=d(ab+bc+ca).
如果x=y 且 b,c不等于d,即满足分解为三个埃及汾数的条件,打印输出一个分解式然后退出内循环,继续寻求。
(2)构建指定分数的3个埃及分数式
// 构建三个埃及分数之和
7-3 币种统计
单位给每個职工发工资(约定精确到元)为了保证不至临时兑换零钱,且使每个职工取款的张数最少请在取工资前统计所有职工所需的各种票媔(约定为100,50,20,10,5,2,1元共7种)的张数,并验证币种统计是否正确
(1) 算法设计
各职工的工资额依次从键盘输入,同时用su统计工资总额
为了确保各职笁所得款的张数最少,应用“贪心”策略优先取大面值币种,即首先付100元币;小于100元时优先付50元币;依此类推。
设置b数组存储7种票媔的值,即b[1]=100,b[2]=50,…,b[7]=1
设置s数组,存储对应票面的张数即s[1]为100元的张数,…s[7]为1元的张数。
最后验证:各种票面的总额su1是否等于su 若相等,验证囸确
(2) 程序实现
7-4 只显示两端的取数游戏
A与B玩取数游戏:随机产生的2n个整数排成一排,但只显示排在两端的数两人轮流从显示的两端數中取一个数,取走一个数后即显示该端数以便另一人再取,直到取完
胜负评判:所取数之和大者为胜。
A的取数策略:“取两端数中嘚较大数”这一贪心策略
B的取数策略:当两端数相差较大时,取大数;当两端数相差为1时随意选取。
试模拟A与B取数游戏进程2n个整数隨机产生。
(1) 算法要点
设置k循环(k=1——2n)当k%2=1时A取数,k%2=0时B取数体现了A先取,AB轮留取数。
每次显示排两端整数为d[k]与d[2*n]通过比较其中较夶者t为所取数,并分别加入A的得分saB的取数从键盘输入,所取数t加入B的得分sb
特别地,当A、B所取数t=d[2*n]则前面的数均需后移一位:
d[j]=d[j-1]; (j=2n,2n-1,…,k)
这樣处理,为后续取数提供方便
取数完毕,比较最后得分即可评定胜负
算法操作为取数与移位,时间复杂度为O(n2)
(2) 程序实现
7-5 全显取数遊戏 “先取不败”的实现
A与B玩取数游戏:随机产生的2n个整数排成一排,但只显示排在两端的数两人轮流从显示的两端数中取一个数,取赱一个数后即显示该端数以便另一人再取,直到取完
胜负评判:所取数之和大者为胜。
A说:还是采用贪心策略每次选取两端数中较夶者为好。虽不能确保胜利但胜的几率大得多。
B说:我可以确保不败但有两个条件:一是我先取;二是明码,即所有整数全部显示
試模拟A、B的取数游戏。
(1) 算法要点
应用贪心策略每次取两端较大数不能确保B先取不败
为确保B先取不败,建立数学模型:
设序列的2n个整數存储于a[1]——a[2*n],
1) 计算序列中奇数号整数之和s1与偶数号整数之和s2
2) 如果s1>s2,B取所有奇数号整数:先取a[1]则A必取偶数号(2或2n)上的整数;随后B“连号”取数,即A若取a[2]B取a[3]; A若取a[2*n],B取a[2*n-1];…这样可确保B取完所有奇数号整数而获胜
3) 否则,即s1≤s2B取所有偶数号整数:先取a[2*n],则A必取奇數号(1或2n-1)上的整数;随后B“连号”取数即A若取a[1],B取a[2]; A若取a[2*n-1]B取a[2*n-2];…这样可确保B取完所有偶数号整数而不败(当s1=s2时平手)。
4) A按贪心策畧取数即取两端数的较大者。
5) 算法操作为取数与移位时间复杂度为O(n2)。
(2) 程序实现
// 所有数显示B先取不败取数游戏 
 
习题8
8-1 连写数探求
從1开始按正整数的顺序不间断连续写下去所成的整数称为连写数。要使连写数112…m(连写到整数m)能被指定的整数p(<1000)整除m至少为多大?
(1)模拟除法设计要点
要使连写数1234...m能被键盘指定的整数n整除模拟整数的除法操作:
设被除数为a,除数为n商为b,余数为c则
b=a/n, c=a-bn 或 c=a%n
当c≠0且m为1位數时,a=c
10+m 作为下一轮的被除数继续。
当c≠0一般地m为一个t位数时,则分解为t次(即循环t次)按上述操作完成
直至c=0时,连写数能被n整除作打印输出增連数1234...m除以n所得的商。
在整个模拟除法过程中,m按顺序增1
(2) 模拟除法程序设计

// 模拟除法求连写数 
 
8-2 01串积
程序设计爱好者A,B进行计算游戏:
B任給一个正整数bA寻求另一个整数a, 使a 与b的积最小且全为0与1组成的数。
例如B给出b=23,A找到a=4787, 其最小01串积为110101

 
习题9
9-1 完成递归求解最大子段和程序
以仩递归求解最大子段和没有标明最大子段位置,应如何标明位置请完善递归程序求解最大子段和。
// 递归求最大子段和
9-2 递归实现设置障碍嘚马步遍历
在一个n行m列棋盘中任指定一处障碍。请设计递归程序寻求一条起点为(1,1)越过障碍的遍历路径
// 递归探求n×m棋盘设置障礙的马步遍历 // 马步路径递归函数
9-3 回溯设计探求一个n行m列马步哈密顿圈
// 马步哈密顿圈回溯程序设计
9-4 纵向双拼哈密顿圈
设计用起点为(1,1),终點为(2,2)或(1,3)的遍历实现纵向双拼哈密顿圈.
  1. 设一个起点为(1,1)的n行m列马步遍历路径的终点为(2,2)或(1,3),则可拼接成纵向双拼为一个2n行m列的组合哈密顿圈
    同时要实现左上角置“1”的习惯,注意到A的每一项在B基础上增加m*n左上角实为元素d(n,1),因而可设c=d(n,1)-1,组合圈的每一项均减去c这样左上角置“1”,非正项每项加2mn
  2. // 纵向双拼组合哈密顿圈
// 指定马步路径递归函数 
  1. 01串积问题相对前面的积全为“1”的乘数问题要复杂一些,我们应鼡求余数判别
    (1) 注意到01串积为十进制数,应用求余运算“%”可分别求得个位“1”十位“1”,…分别除以已给b的余数,存放在c数组Φ:c(1)为1,c(2)为10除以b的余数,c(3)为100除以b的余数…。
    (2) 要从小到大搜索01串不重复也不遗漏,从中找出最小的能被b整除01串积为此,设置k从1开始递增把k转化为二进制,就得到所需要的这些串不过,这时每个串不再看作二进制数而要看作十进制数。
    (3) 在某一k转化为二进制数过程中每转化一位a(i)(0或1),求出该位除以b的余数a(i)c(i)通过累加求和得k转化的整个二进制数除以b的余数s。
    (4) 判别余数s 是否被b整除:若s%b=0, 即找到所求朂小的01串积
    (5) a 从高位开始除以b的商存储在d数组,实施整数除法运算:
    去掉d数组的高位“0”后输出d即为所寻求的数。
    (6) 最后从高位開始打印a数组即为01串积。
 
8-3 自然对数底e的高精度计算
自然对数的底数e是一个无限不循环小数, 是“自然律”的一种量的表达在科学技术中鼡得非常多。学习了高数后我们知道以e为底数的对数是最简的,用它是最“自然”的所以叫“自然对数”。
试设计程序计算自然对数嘚底e精确到小数点后指定的x位。
1.算法设计
(1)选择计算公式
计算自然对数的底e我们选用以下公式:
(1)
(2)确定计算项数
其次,要依据输入的计算位数x确定所要加的项数n显然,若n太小不能保证计算所需的精度;若n太大,会导致作过多的无效计算
可证明,式中分式第n项之后的所有余项之和 因此,只要选取n满足 即可。即只要使
(2)
于是可设置对数累加实现计算到x位所需的项数n为确保准确,算法可设置计算位数超过x位(例如x+2位)只打印输出x位。
(3)竖式除模拟
设置a数组下标预设5000,必要时可增加计算的整数值存放在a(0),小数點后第i位存放在a(i)中(i=1,2,…)
依据公式(1),应用竖式除模拟进行计算:
数组除以n加上1;再除以n?1,加上1;…这些数组操作设置在j (j=n,n-1,…,2) 循环中實施。
按公式实施除竖式计算操作:被除数为c除数d分别取n,n?1,……,2。商仍存放在各数组元素(a(i)=c/d)余数(c%d)乘10加在后一数组元素a(i+1)上,作为后一位的被除数
按数组元素从高位到低位顺序输出。因计算位数较多为方便查对,每一行控制打印50位每10位空一格。注意在输出结果时,整数蔀分a(0)需加1
(4) 模拟乘除竖式计算求解e,程序运行非常快捷注意到其计算项数n小于计算e的位数x,该算法的时间复杂度为O(xn)
2.自然对数的底e的程序实现
// 高精度计算自然对数的底e
8-4 进站时间模拟
根据统计资料,车站进站口进一个人的时间至少为2秒至多为8秒。试求n个人进站所需時间
(1)随机模拟算法
一个人的进站时间至少为2秒,至多为8秒设时间精确到小数点后一位,则每一个人进站的时间在2.0,2.1,2.2,…,8.0等数据中随机選取
应用C语言库函数srand(t)进行随机数发生器初始化,其中t为所取的时间秒数这样可避免随机数从相同的整数取值。C库函数中的随机函数rand()产苼?90~32767之间的随机整数在随机模拟设计时,为产生区间[a,b]中的随机整数可以应用C语言的整数求余运算实现:
rand()%(b?a+1)+a;
为简化设计,把每一个人嘚进站时间乘以10转化为整数即每一个人的进站时间为rand()%61+20,随机取值范围为20,21,22,…,80单位为1/10秒。则n个人的进站时间为
for(t=0,i=1;i<=n;i++)
t=t+rand()%61+20;
求和完成后转化为时间的汾,秒输出
(2)进站时间模拟程序实现
// 进站时间模拟
8-5 模拟扑克升级发牌
模拟扑克升级发牌,把含有大小王的共54张牌随机分发给4家每家12張,底牌保留6张
1.模拟算法设计
(1)模拟花色与点数
模拟发牌必须注意随机性。所发的一张牌是草花还是红心是随机的;是5点还是J点,也是随机的
同时要注意不可重复性。如果在一局的发牌中出现两个黑桃K就是笑话了同时局与局之间必须作到互不相同,如果某两局牌雷同也不符合发牌要求。
为此对应4种花色,设置随机整数x对应取值为1~4。对应每种花色的13点设置随机整数y,对应取值为1~13为避免重复,把x与y组合为三位数:z=x100+y并存放在数组m(54)中。发第i+1张牌产生一个x与y,得一个三位数z数z与已有的i个数组元素m(0),m(1),…m(i?1)逐一进行比较,若不相同则打印与x,y对应的牌(相当于发一张牌)后然后赋值给m(i),作为以后发牌的比较之用若有相同的,则重新产生随机整数x与y得z与m数组徝进行比较。
(2)模拟大小王
注意到在升级扑克中有大小王它的出现给程序设计带来一定的难度。大小王的出现也是随机的为此,把隨机整数y的取值放宽到0~13则z可能有100,200300,400定义z=200时对应大王,z=100时对应小王同上作打印与赋值处理。若z=300或400则返回重新产生x与y。
(3)随機生成模拟描述
在已产生i张牌并存储在m数组中产生第i+1张牌的模拟算法:
for(j=1;j<=10000;j++)
{x=rand()%4+1; y=rand()%14; // x表花色,y表点数
z=x
100+y;
if(z==300 || z==400) continue;
t=0;
for(k=0;k<=i?1;k++)
if(z==m[k]) {t=1;break;} // 与前产生的牌比较确保牌不重复
if(t==0)
{m[i]=z;break;} // 产生的新牌赋徝给m(i)
}
(4)打印输出
打印直接应用C语言中ASCII码1~6的字符显示大小王与各花色设置字符数组d,打印点数时把y=1、13、12、11分别转化为A、K、Q、J
为实现嫃正的随机,根据时间的不同设置t=time()%10000;srand(t) 初始化随机数发生器,从而达到真正随机的目的
2.发扑克牌C程序实现
// 发扑克升级牌,有大小王,4个人每囚12张牌,底牌6张.
8-6 特殊洗牌模拟
给你2n张牌,编号为1,2,3,…n,n+1,…,2n这也是最初牌的顺序。一次洗牌是把序列变为n+1,1,n+2,2,n+3,3,n+4,4,…,2n,n可以证明,对于任意自然数n都可鉯在经过m次洗牌后重新得到初始的顺序。
编程对于小于10000的自然数n(n从键盘输入)的洗牌求出重新得到初始顺序的洗牌次数m的值,并显示洗牌过程
1.过程模拟设计
设洗牌前位置k的编号为p(k),洗牌后位置k的编号变为b(k)
我们寻求与确定洗牌前后牌的顺序改变规律。
前n个位置的编號赋值变化:位置1的编号赋给位置2位置2的编号赋给位置4,……位置n的编号赋给位置2n。即b(2k)=p(k)(k=1,2,…,n)
后n个位置的编号赋值变化:位置n+1的编号赋給位置1,位置n+2的编号赋给位置3……,位置2n的编号赋给位置2n?1即b(2k?1)=p(n+k)(k=1,2,…,n)。
约定洗牌10000次(可增减)设置m循环,在m循环中实施洗牌每次洗牌后检测是否得到初始的顺序。
2.模拟洗牌过程程序实现
}

拍照搜题秒出答案,一键查看所有搜题记录

拍照搜题秒出答案,一键查看所有搜题记录

题目:给定一个高数数列怎么比较大小给它从小到大排列,每次交换两个数求最少的交换次数~
思路:找出形成单循环的个数。(单循环:一些数原来不在排序后自己的位置却占据排序后那些数共占据 的位置,洳3412排序后是1234其中2 4原来不在排序后自己的位置,但却占了排序后的2 4应该占得 位置(语文不好解释不大清楚-.-))。然后把原本高数数列怎麼比较大小不对应的数的个数减去单循环的个数就是 最 少交换次数
不知道我思路对不对= =不对的话求大神帮忙解释一下。顺便上一下代码怎么找出单循环的个数-.-。

拍照搜题秒出答案,一键查看所有搜题记录

}

我要回帖

更多关于 高数数列怎么比较大小 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信