算法设计与分析习题答案1-6章. 联系客服

发布时间 : 星期二 文章算法设计与分析习题答案1-6章.更新完毕开始阅读e080519a8ad63186bceb19e8b8f67c1cfad6eef4

r = (i%4==1)?r+f:r-f;

e = e*sqr;//e每次乘于x的平方 i+=2;//i每次加2 }//while return r; }

7. 圣经上说:神6天创造天地万有,第7日安歇。为什么是6天呢?任何一个自然数的因数中都有1和它本身,所有小于它本身的因数称为这个数的真因数,如果一个自然数的真因数之和等于它本身,这个自然数称为完美数。例如,6=1+2+3,因此6是完美数。神6天创造世界,暗示着该创造是完美的。设计算法,判断给定的自然数是否是完美数

#include using namespace std;

int main() {

int value, k=1; cin>>value;

for (int i = 2;i!=value;++i) {

while (value % i == 0 ) {

k+=i;//k为该自然数所有因子之和 value = value/ i; }

}//for

if(k==value)

cout<<\该自然数是完美数\ else

cout<<\该自然数不是完美数\ return 0; }

8. 有4个人打算过桥,这个桥每次最多只能有两个人同时通过。他们都在桥的某一端,并且是在晚上,过桥需要一只手电筒,而他们只有一只手电筒。这就意味着两个人过桥后必须有一个人将手电筒带回来。每个人走路的速度是不同的:甲过桥要用1分钟,乙过桥要用2分钟,丙过桥要用5分钟,丁过桥要用10分钟,显然,两个人走路的速度等于其中较慢那个人的速度,问题是他们全部过桥最少要用多长时间?

由于甲过桥时间最短,那么每次传递手电的工作应有甲完成 甲每次分别带着乙丙丁过桥 例如:

第一趟:甲,乙过桥且甲回来 第二趟:甲,丙过桥且甲回来 第一趟:甲,丁过桥 一共用时19小时

9.欧几里德游戏:开始的时候,白板上有两个不相等的正整数,两个玩家交替行动,每次行动时,当前玩家都必须在白板上写出任意两个已经出现在板上的数字的差,而且这个数字必须是新的,也就是说,和白板上的任何一个已有的数字都不相同,当一方再也写不出新数字时,他就输了。请问,你是选择先行动还是后行动?为什么?

设最初两个数较大的为a, 较小的为b,两个数的最大公约数为factor。

则最终能出现的数包括: factor, factor*2, factor*3, ..., factor*(a/factor)=a. 一共a/factor个。

如果a/factor 是奇数,就选择先行动;否则就后行动。

习题4

1. 分治法的时间性能与直接计算最小问题的时间、合并子问题解的时间以及子问题的个数有关,试说明这几个参数与分治法时间复杂性之间的关系。

2. 证明:如果分治法的合并可以在线性时间内完成,则当子问题的规模之和小于原问题的规模时,算法的时间复杂性可达到O(n)。

O(N)=2*O(N/2)+x

O(N)+x=2*O(N/2)+2*x

a*O(N)+x=a*(2*O(N/2)+x)+x=2*a *O(N/2)+(a+1)*x 由此可知,时间复杂度可达到O(n);

3.分治策略一定导致递归吗?如果是,请解释原因。如果不是,给出一个不包含递归的分治例子,并阐述这种分治和包含递归的分治的主要不同。

不一定导致递归。

如非递归的二叉树中序遍历。

这种分治方法与递归的二叉树中序遍历主要区别是:应用了栈这个数据结构。

4. 对于待排序序列(5, 3, 1, 9),分别画出归并排序和快速排序的递归运行轨迹。

归并排序:

第一趟:(5,3)(1,9); 第二趟:(3,5,1,9); 第三趟:(1,3,5,9);

快速排序:

第一趟:5( ,3,1,9);//5为哨兵,比较9和5 第二趟:5(1,3, ,9);//比较1和5,将1挪到相应位置; 第三趟:5(1,3, ,9);//比较3和5; 第四趟:(1,3,5,9);

5. 设计分治算法求一个数组中的最大元素,并分析时间性能。

//简单的分治问题

//将数组均衡的分为“前”,“后”两部分

//分别求出这两部分最大值,然后再比较这两个最大值

#include using namespace std;

extern const int n=6;//声明 int main() { int a[n]={0,6,1,2,3,5};//初始化 int mid=n/2; int num_max1=0,num_max2=0; for(int i=0;i<=n/2;++i)//前半部分 { if(a[i]>num_max1) num_max1=a[i]; } for(int j=n/2+1;jnum_max2) num_max2=a[j]; } if(num_max1>=num_max2) cout<<\数组中的最大元素: \ else

cout<<\数组中的最大元素: \ return 0; }

时间复杂度:O(n)

6. 设计分治算法,实现将数组A[n]中所有元素循环左移k个位置, 要求时间复杂性为O(n),空间复杂性为O(1)。例如,对abcdefgh循环左移3位得到defghabc。

//采用分治法

//将数组分为0-k-1和k-n-1两块 //将这两块分别左移 //然后再合并左移

#include using namespace std;

void LeftReverse(char *a, int begin, int end) {

for(int i=0;i<(end-begin+1)/2;i++)//交换移动 {

int temp=a[begin+i]; a[begin+i]=a[end-i]; a[end-i]=temp; } }

void Converse(char *a,int n,int k) {

LeftReverse(a, 0, k-1); LeftReverse(a, k, n-1); LeftReverse(a, 0, n-1); for(int i=0;i

int main() {

char a[7]={'a','b','c','d','e','f','g'}; Converse(a,7,3); return 0; }

7. 设计递归算法生成n个元素的所有排列对象。 #include