最新算法与分析平时作业---答案
- 格式:doc
- 大小:101.50 KB
- 文档页数:11
算法设计与分析习题答案算法设计与分析是计算机科学中一个重要的领域,它涉及到算法的创建、优化以及评估。
以下是一些典型的算法设计与分析习题及其答案。
习题1:二分查找算法问题描述:给定一个已排序的整数数组,编写一个函数来查找一个目标值是否存在于数组中。
答案:二分查找算法的基本思想是将数组分成两半,比较中间元素与目标值的大小,如果目标值等于中间元素,则查找成功;如果目标值小于中间元素,则在左半部分继续查找;如果目标值大于中间元素,则在右半部分继续查找。
这个过程会不断重复,直到找到目标值或搜索范围为空。
```pythondef binary_search(arr, target):low, high = 0, len(arr) - 1while low <= high:mid = (low + high) // 2if arr[mid] == target:return Trueelif arr[mid] < target:low = mid + 1else:high = mid - 1return False```习题2:归并排序算法问题描述:给定一个无序数组,使用归并排序算法对其进行排序。
答案:归并排序是一种分治算法,它将数组分成两半,分别对这两半进行排序,然后将排序好的两半合并成一个有序数组。
```pythondef merge_sort(arr):if len(arr) > 1:mid = len(arr) // 2left_half = arr[:mid]right_half = arr[mid:]merge_sort(left_half)merge_sort(right_half)i = j = k = 0while i < len(left_half) and j < len(right_half): if left_half[i] < right_half[j]:arr[k] = left_half[i]i += 1else:arr[k] = right_half[j]j += 1k += 1while i < len(left_half):arr[k] = left_half[i]i += 1k += 1while j < len(right_half):arr[k] = right_half[j]j += 1k += 1arr = [38, 27, 43, 3, 9, 82, 10]merge_sort(arr)print("Sorted array is:", arr)```习题3:动态规划求解最长公共子序列问题问题描述:给定两个序列,找到它们的最长公共子序列。
算法设计与分析基础习题1.15..证明等式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<n的一对数字,Euclid算法在第一次叠代时交换m和n, 即gcd(m,n)=gcd(n,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//输出:实根或者无解信息If a≠0D←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. 这个断言是正确的。
《算法分析与设计》作业(一)本课程作业由两部分组成。
第一部分为“客观题部分”,由15个选择题组成,每题1分,共15分。
第二部分为“主观题部分”,由简答题和论述题组成,共15分。
作业总分30分,将作为平时成绩记入课程总成绩。
客观题部分:一、选择题(每题1分,共15题)1、递归算法:(C )A、直接调用自身B、间接调用自身C、直接或间接调用自身D、不调用自身2、分治法的基本思想是将一个规模为n的问题分解为k个规模较小的字问题,这些子问题:(D )A、相互独立B、与原问题相同C、相互依赖D、相互独立且与原问题相同3、备忘录方法的递归方式是:(C )A、自顶向下B、自底向上C、和动态规划算法相同D、非递归的4、回溯法的求解目标是找出解空间中满足约束条件的:(A )A、所有解B、一些解C、极大解D、极小解5、贪心算法和动态规划算法共有特点是:(A )A、最优子结构B、重叠子问题C、贪心选择D、形函数6、哈夫曼编码是:(B)A、定长编码B、变长编码C、随机编码D、定长或变长编码7、多机调度的贪心策略是:(A)A、最长处理时间作业优先B、最短处理时间作业优先C、随机调度D、最优调度8、程序可以不满足如下性质:(D )A、零个或多个外部输入B、至少一个输出C、指令的确定性D、指令的有限性9、用分治法设计出的程序一般是:(A )A、递归算法B、动态规划算法C、贪心算法D、回溯法10、采用动态规划算法分解得到的子问题:( C )A、相互独立B、与原问题相同C、相互依赖D、相互独立且与原问题相同11、回溯法搜索解空间的方法是:(A )A、深度优先B、广度优先C、最小耗费优先D、随机搜索12、拉斯维加斯算法的一个显著特征是它所做的随机选性决策有可能导致算法:( C )A、所需时间变化B、一定找到解C、找不到所需的解D、性能变差13、贪心算法能得到:(C )A、全局最优解B、0-1背包问题的解C、背包问题的解D、无解14、能求解单源最短路径问题的算法是:(A )A、分支限界法B、动态规划C、线形规划D、蒙特卡罗算法15、快速排序算法和线性时间选择算法的随机化版本是:( A )A、舍伍德算法B、蒙特卡罗算法C、拉斯维加斯算法D、数值随机化算法主观题部分:二、写出下列程序的答案(每题2.5分,共2题)1、请写出批处理作业调度的回溯算法。
算法设计与分析基础课后练习答案习题1.14.设计一个计算的算法,n是任意正整数。
除了赋值和比较运算,该算法只能用到基本的四则运算操作。
算法求//输入:一个正整数n2//输出:。
step1:a=1;step2:若a*a<n 转step 3,否则输出a;step3:a=a+1转step 2;5. a.用欧几里德算法求gcd(31415,14142)。
b. 用欧几里德算法求gcd(31415,14142),比检查min{m,n}和gcd (m,n)间连续整数的算法快多少倍?请估算一下。
a. gcd(31415, 14142) = gcd(14142, 3131) = gcd(3131, 1618) =gcd(1618, 1513) = gcd(1513, 105) = gcd(1513, 105) = gcd(105, 43) =gcd(43, 19) =gcd(19, 5) = gcd(5, 4) = gcd(4, 1) = gcd(1, 0) = 1.b.有a可知计算gcd(31415,14142)欧几里德算法做了11次除法。
连续整数检测算法在14142每次迭代过程中或者做了一次除法,或者两次除法,因此这个算法做除法的次数鉴于1·14142 和2·14142之间,所以欧几里德算法比此算法快1·14142/11 ≈ 1300 与2·14142/11 ≈ 2600 倍之间。
6.证明等式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)具有相同的公约数的有限非空集,其中也包括了最大公约数。
算法分析与设计作业及参考答案作业题目1、请分析冒泡排序算法的时间复杂度和空间复杂度,并举例说明其在实际中的应用场景。
2、设计一个算法,用于在一个未排序的整数数组中找到第二大的元素,并分析其时间复杂度。
3、比较贪心算法和动态规划算法的异同,并分别举例说明它们在解决问题中的应用。
参考答案1、冒泡排序算法时间复杂度:冒泡排序的基本思想是通过相邻元素的比较和交换,将最大的元素逐步“浮”到数组的末尾。
在最坏情况下,数组完全逆序,需要进行 n 1 轮比较和交换,每一轮比较 n i 次(i 表示当前轮数),所以总的比较次数为 n(n 1) / 2,时间复杂度为 O(n^2)。
在最好情况下,数组已经有序,只需要进行一轮比较,时间复杂度为 O(n)。
平均情况下,时间复杂度也为 O(n^2)。
空间复杂度:冒泡排序只在原数组上进行操作,不需要额外的存储空间,空间复杂度为 O(1)。
应用场景:冒泡排序算法简单易懂,对于规模较小的数组,或者对算法的简单性要求较高而对性能要求不是特别苛刻的场景,如对少量数据进行简单排序时,可以使用冒泡排序。
例如,在一个小型的学生成绩管理系统中,需要对一个班级的少量学生成绩进行排序展示,冒泡排序就可以满足需求。
2、找到第二大元素的算法以下是一种使用遍历的方法来找到未排序整数数组中第二大元素的算法:```pythondef find_second_largest(arr):largest = arr0second_largest = float('inf')for num in arr:if num > largest:second_largest = largestlargest = numelif num > second_largest and num!= largest:second_largest = numreturn second_largest```时间复杂度分析:这个算法需要遍历数组一次,所以时间复杂度为O(n)。
平时作业1、给定下述二分搜索算法,请判断算法的正确性,指出错误算法的产生原因。
a) int BinarySearch(Type a[], const Type& x, int l, int r){while (r >= l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m-1;else l = m+1;}return -1;}答:正确b) int BinarySearch(Type a[], const Type& x, int l, int r){while (r >= l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m+1;else l = m-1;}return -1;}答:错误if (x < a[m]) r = m+1; 当查找的元素在中间元素的左边时,右指针应该为m-1位置,修改成if (x < a[m]) r = m+1; else l = m+lc) int BinarySearch(Type a[], const Type& x, int l, int r){while (r > l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m-1;else l = m+1;}return -1;}答:错误。
while (r > l) 要考虑到数组只有一个元素的情况所以应该是 r>=l ;2、O(1)空间子数组环卫算法:设a[0:n-1]是一个n维数组,k(1≤ k ≤n-1)是一个非负整数。
试设计一个算法将子数组a[0 : k-1]与a[k+1 : n-1]换位。
要求算法在最坏情况下耗时O(n),且只用O(1)的辅助空间。
平时作业1、给定下述二分搜索算法,请判断算法的正确性,指出错误算法的产生原因。
a) int BinarySearch(Type a[], const Type& x, int l, int r){while (r >= l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m-1;else l = m+1;}return -1;}答:正确b) int BinarySearch(Type a[], const Type& x, int l, int r){while (r >= l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m+1;else l = m-1;}return -1;}答:错误if (x < a[m]) r = m+1; 当查找的元素在中间元素的左边时,右指针应该为m-1位置,修改成if (x < a[m]) r = m+1; else l = m+lc) int BinarySearch(Type a[], const Type& x, int l, int r){while (r > l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m-1;else l = m+1;}return -1;}答:错误。
while (r > l) 要考虑到 数组只有一个元素的情况 所以应该是 r>=l ;2、O(1)空间子数组环卫算法:设a[0:n-1]是一个n 维数组,k (1≤ k ≤n-1)是一个非负整数。
试设计一个算法将子数组a[0 : k-1]与a[k+1 : n-1]换位。
要求算法在最坏情况下耗时O(n),且只用O(1)的辅助空间。
《算法设计与分析》试卷1一、多项选择题(每空2分, 共20分):1.以下关于算法设计问题的叙述中正确的是__________。
A.计算机与数值问题的求解——方程式求根、插值问题、数值积分、函数逼近等有关B.利用计算机无法解决非数值问题C.计算机在解决分类、语言翻译、图形识别、解决高等代数和组合分析等方面的数学问题、定理证明、公式推导乃至日常生活中各种过程的模拟等问题中, 主要进行的是判断、比较, 而不是算术运算D、算法设计与分析主要研究对象是非数值问题, 当然也包含某些数值问题2.算法的特征包括_________。
A.有穷性B、确定性C.输入和输出D.能行性或可行性3、以下描述是有关算法设计的基本步骤:①问题的陈述②算法分析③模型的拟制④算法的实现⑤算法的详细设计⑥文档的编制, 应与其它环节交织在一起其中正确的顺序是__________。
A.①②③④⑤⑥B.①③⑤②④⑥C.②④①③⑤⑥D.⑥①③⑤②④4.以下说法正确的是__________。
A.数学归纳法可以证明算法终止性B.良序原则是证明算法的正确性的有力工具C. x = 小于或等于x的最大整数(x的低限)D. x = 小于或等于x的最大整数(x的高限)5、汉诺塔(Hanoi)问题中令h(n)为从A移动n个金片到C上所用的次数, 则递归方程为__________, 其初始条件为__________, 将n个金片从A柱移到C柱上的移动次数是__________;设菲波那契(Fibonacci)数列中Fn为第n个月时兔子的对数, 则有递归方程为__________, 其中F1=F2=__________。
A.Fn=Fn-1+Fn-2 B、h(n)= 2h(n-1)+1C.1 D、h(1)= 1E、h(n)=2n-1F、06.在一个有向连通图中(如下图所示), 找出点A到点B的一条最短路为____ ______。
A.最短路: 1→3→5→8→10, 耗费: 20B、最短路:1→4→6→9→10, 耗费:16C.最短路: 1→4→6→9, 耗费: 12D.最短路: 4→6→9→10, 耗费: 13二、填空(每空2分, 共20分):1.快速排序法的基本思想是重新排列关键字, 把一个文件分成两个文件, 使得第一个文件中所有元素均小于第二个文件中的元素;然后再对两个子文件进行同样的处理。
平时作业1、给定下述二分搜索算法,请判断算法的正确性,指出错误算法的产生原因。
a) int BinarySearch(Type a[], const Type& x, int l, int r){while (r >= l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m-1;else l = m+1;}return -1;}答:正确b) int BinarySearch(Type a[], const Type& x, int l, int r){while (r >= l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m+1;else l = m-1;}return -1;}答:错误if (x < a[m]) r = m+1; 当查找的元素在中间元素的左边时,右指针应该为m-1位置,修改成if (x < a[m]) r = m+1; else l = m+lc) int BinarySearch(Type a[], const Type& x, int l, int r){while (r > l){int m = (l+r)/2;if (x == a[m]) return m;if (x < a[m]) r = m-1;else l = m+1;}return -1;}答:错误。
while (r > l) 要考虑到数组只有一个元素的情况所以应该是 r>=l ;2、O(1)空间子数组环卫算法:设a[0:n-1]是一个n维数组,k(1≤k ≤n-1)是一个非负整数。
试设计一个算法将子数组a[0 : k-1]与a[k+1 : n-1]换位。
要求算法在最坏情况下耗时O(n),且只用O(1)的辅助空间。
答:最简单的方法就是循环(n-k-1)次,将a 数组的末尾数字插入到a[0]之前。
具体做法:(1) 首先开辟一个额外空间temp 用于存放每一次a 数组的末尾数据。
(2) temp <- a[n-1](3) 将a[0: n-2] 每个数据都依次向后移动一位赋值给a[1: n-1]。
(4) a[0] <- temp(5) 循环执行(2) -(4) 步 (n-k+1)次。
代价分析: 时间代价—— O((n-1)*(n-k+1)) 即O(n^2)数量级;空间代价: O (1)3、定义: 给定一个自然数n ,由n 开始依次产生半数集set(n)中的元素如下:1)()n set n ∈;2)在n 的左边加上一个自然数,但该自然数不能超过最近添加的数的一半;3)按此规则进行处理,直至不能再添加新的自然数为止。
例如 (){6,16,26,126,36,136}set n =。
其中共有6个元素。
半数集问题:对于给定的n ,求半数集set(n) 中元素的个数。
答:半数集set(n)中元素个数的求解是个递归的过程。
设set(n)中的元素个数为f(n),则显然有递归表达式:f(n)=1+∑f(i),i=1,2……n/2。
即半数集set(n)元素个数f(n)=1+f(1)+f(2)+...+f(floor(n/2)). 用递推法求解。
C 语言代码如下:#include<stdio.h>#include<stdlib.h>int main(){int n;int i,j,s;int buf[106];char *in="input.txt",*out="output.txt";FILE *ip,*op;if((ip=fopen(in,"r"))==NULL)return 1;if((op=fopen(out,"w"))==NULL)return 2;fscanf(ip,"%d",&n);fclose(ip);buf[1]=1;buf[2]=2;buf[3]=2;for(i=4;i*2<=n;i++){s=1;for(j=1;j<=i/2;j++){s+=buf[j];}buf[i]=s;}s=1;for(j=1;j<=n/2;j++){s+=buf[j];}fprintf(op,"%d",s);fclose(op);/* system("pause");*/return 0;}4、设计一个算法,找出由n个数组成的序列的最长单调递增子序列的长度。
答:#include<iostream.h> #define m 10//快速排序void QuickSort(int R[],int s,int t) {int i=s,j=t; int tmp;if(s<t) {tmp=R[s];while(i!=j) {while(j>i&&R[j]>=tmp) j--;R[i]=R[j];while(i<j&&R[i]<=tmp) i++;R[j]=R[i];}R[i]=tmp;QuickSort(R,s,i-1);QuickSort(R,i+1,t);}}//找出最长公共子序列void LCSLength(int x[],int y[],int n,int c[m][m],int b[m][m]) {int i,j; for(i=0;i<n;i++) {c[0][i]=0; c[i][0]=0;}for(i=0;i<n;i++) for(j=0;j<n;j++) {if(x[i]==y[j]) {c[i][j]=c[i-1][j-1]+1; b[i][j]=1;} else if(c[i-1][j]>=c[i][j-1]) {c[i][j]=c[i-1][j];b[i][j]=2;} else {c[i][j]=c[i][j-1]; b[i][j]=3;}}}void LCS(int i,int j,int *x,int b[m][m]) {if(i<0||j<0) return; if(b[i][j]==1) {LCS(i-1,j-1,x,b); cout<<x[i]<<" ";} else if(b[i][j]==2) LCS(i-1,j,x,b);else LCS(i,j-1,x,b);}void main() {int x[m],y[m],d;cout<<"请输入元素个数"<<endl; cin>>d;cout<<"请输入元素"<<endl;for(int i=0;i<d;i++) {cin>>x[i]; y[i]=x[i];}int c[m][m]={0},b[m][m]={0};QuickSort(x,0,d-1);LCSLength(x,y,d,c,b);cout<<"最长单调递增子序列为:"<<endl; LCS(d-1,d-1,x,b);}5、会场安排问题:假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。
设计一个有效的贪心算法进行安排。
对于给定的n个待安排的活动,计算使用最少会场的个数。
每个活动i都有一个开始时间和结束时间,分别表示为b(i),f(i)。
答:#include<iostream>using namespace std;#define M 50//最大活动数struct Active {int b;//开始时间int f;//结束时间int no;//预安排会场号}a[M];//两元素交换位置void swap(Active &a,Active &b){Active t=a; a=b; b=t;}void main(){int k, i,j;cout<<"输入待安排活动数:"<<endl;cin>>k;cout<<"输入待安排活动的开始时间和结束时间:"<<endl; //输入活动时间//活动时间排序for(i=1;i<=k;i++) {{ for(j=i;j<=k;j++) {if(a[i].b>a[j].b) swap(a[i],a[j]);if(a[i].b==a[j].b){if(a[i].f>a[j].f) swap(a[i],a[j]);}}}int int sum=1;//使用的会场数初始化int n; a[1].no=sum;for(i=2;i<=k;i++) {for(n=1;n<i;n++) {if(a[n].no!=0&&a[n].f<=a[i].b) {a[i].no=a[n].no;a[n].no=0;//已经安排过的活动就不再比较 break;}}if(n==i){sum+=1; a[i].no=sum;}}cout<<"输出最少会场数:\n"<<sum<<endl;system("pause");}6、最优分解问题:设n是一个正整数。
现要求将n分解为若干个互不相同的自然数的和,使得这些自然数的乘积最大。
设计一个算法,得到最优分解方案。
分析:我们知道如果a+b=常数,则|a-b|越小,a*b越大。
贪心策略:将n 分成从2开始的连续自然数的和。
如果最后剩下一个数,将此数在后项优先的方式下均匀地分给前面各项。
答:void dicomp(int n, int[] a){int k = 1;if (n < 3) { a[1] = 0; return; }if (n < 5) { a[k] = 1; a[++k] = n - 1; return; }a[1] = 2;n -= 2;while (n > a[k]) {k++;a[k] = a[k - 1] + 1;n -= a[k];}if (n == a[k]) {a[k]++; n--;}for (int i = 0; i < n; i++) a[k - i]++;}7、子集和问题:设12{,,,}n S x x x =是n 个正整数的集合,c 是一个正整数。