算法设计与分析实验报告-分治法相关练习题

课本分治法章节课后部分练习题。

算法设计与分析实验报告-递归与分治策略

算法设计与分析实验报告-动态规划算法

算法设计与分析实验报告-回溯法

算法设计与分析实验报告-分治法相关练题

北京大学出版社-算法设计与分析


五、程序题

1. 试给出用分治法求某集合中元素值为偶数的元素个数的程序代码。

2. 试给出用i分治法求某集合中元素值为最大数的程序代码。

3. 根据分治法求某集合中元素值大于指定值的元素个数。要求给出分治法解决该问题的基本思路并给出递归实现代码。

4. 根据分治法求解棋盘覆盖问题。试写出该程序代码,可以只写函数

5. 给出归并排序的核心代码,并分析归并排序的时间复杂性。

6. 给出快速排序算法,以及快速排序的Partition函数。

7. 给出分治法设计的循环赛日程表。

8. 用分治法写出有序序列进行二分查找的过程

9. 对给定的含有n个元素的无序序列,求这个元素中第K小的元素


分治法求某集合中元素值大于指定值的元素个数。基本思路:将求解范围l~r分为两半,变成2个子问题,递归求解两个子问题,再将两个子问题的解加和得到原问题解。 
递归出口:只有一个元素时与指定元素进行比较返回答案1或0. 
递归关系:两个子问题的解相加为原问题解。 
参数设置:数组arr,起始位置l,终点位置r,指定比较值x。

1. 试给出用分治法求某集合中元素值为偶数的元素个数的程序代码。
//
// Created by GiperHsiue on 2022/10/17.
//
// 分治法求某集合中元素值为偶数的元素个数。
#include <iostream>
using namespace std;
int check(int arr[], int l, int r){if(l == r) return arr[l] % 2 ? 0 : 1;int mid = l + r >> 1;return check(arr, l, mid) + check(arr, mid + 1, r);
}
int main(){int n;cin >> n;int *arr = new int[n];for(int i = 0; i < n; i ++) cin >> arr[i];cout << check(arr, 0, n - 1);return 0;
}

运行如下:


2. 试给出用分治法求某集合中元素值为最大数的程序代码。
//
// Created by GiperHsiue on 2022/10/17.
//
//分治法求某集合中元素值为最大数。
#include <iostream>
#include <algorithm>
using namespace std;
int check(int arr[], int l, int r){if(l == r) return arr[l];int mid = l + r >> 1;return max(check(arr, l, mid), check(arr, mid + 1, r));
}
int main(){int n;cin >> n;int *arr = new int[n];for(int i = 0; i < n; i ++) cin >> arr[i];cout << check(arr, 0, n - 1);return 0;
}

测试如下:


3. 根据分治法求某集合中元素值大于指定值的元素个数。要求给出分治法解决该问题的基本思路并给出递归实现代码。
//
// Created by GiperHsiue on 2022/10/17.
//
#include <iostream>
#include <algorithm>
using namespace std;
int check(int arr[], int l, int r, int x){if(l == r) return arr[l] > x ? 1 : 0;int mid = l + r >> 1;return check(arr, l, mid, x) + check(arr, mid + 1, r, x);
}
int main(){int n, x;cin >> n;int *arr = new int[n];for(int i = 0; i < n; i ++) cin >> arr[i];cin >> x;cout << check(arr, 0, n - 1, x);return 0;
}

测试如下:

4. 根据分治法求解棋盘覆盖问题。试写出该程序代码,可以只写函数。
//
// Created by GiperHsiue on 2022/10/20.
//
//棋盘覆盖问题
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
char tile = '1'; // 骨牌的编号
char **board;
//(r,c)棋盘左上角坐标,(sr,sc)特殊方格坐标,size棋盘的行(列)数
void cb(int r, int c, int sr, int sc, int size){if(size == 1) return;int t = tile++;int s = size / 2;//左上角if(sr < r + s && sc < c + s){cb(r, c, sr, sc, s);} else{board[r + s -1][c + s - 1] = t;cb(r, c, r + s - 1, c + s - 1, s);}//右上角if(sr < r + s && sc >= c + s){cb(r, c + s, sr, sc, s);} else{board[r + s -1][c + s] = t;cb(r, c + s, r + s - 1, c + s, s);}//左下角if(sr >= r + s && sc < c + s){cb(r + s, c, sr, sc, s);} else{board[r + s][c + s - 1] = t;cb(r + s, c, r + s, c + s - 1, s);}//右下角if(sr >= r + s && sc >= c + s){cb(r + s, c + s, sr, sc, s);} else{board[r + s][c + s] = t;cb(r + s, c + s, r + s, c + s, s);}
}
int main(){int k;cout << "棋盘大小2^k * 2^k 输入K:";cin >> k;int n = pow(2, k);board = new char*[n]; //动态创建棋盘数组for(int i = 0; i < n; i ++) board[i] = new char[n];for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {board[i][j] = '.';}}cout << "输入特殊方格位置:";int sr, sc;cin >> sr >> sc;board[sr][sc] = '*';cout << "初始化:" << endl;for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {cout << setw(4) << board[i][j];}cout << endl;}cb(0, 0, sr, sc, n);cout << "覆盖后:" << endl;for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {if(i == sr && j == sc) cout << setw(4) << board[i][j];else cout << setw(4) << board[i][j] - '0';}cout << endl;}return 0;
}

测试如下:

5. 给出归并排序的核心代码,并分析归并排序的时间复杂性。
//
// Created by GiperHsiue on 2022/10/20.
//
//归并排序
#include <iostream>
using namespace std;
int n;void mergeSort(int a[], int l, int r){if(l >= r) return;int mid = (l + r) / 2;mergeSort(a, l, mid), mergeSort(a, mid + 1, r);//merge过程int k = 0, i = l, j = mid + 1;int *tmp = new int[n]();while (i <= mid && j <= r) {if (a[i] <= a[j]) tmp[k++] = a[i++];else tmp[k++] = a[j++];}while(i <= mid) tmp[k++] = a[i++];while (j <= r) tmp[k++] = a[j++];//copy过程for (i = l, j = 0;i <= r; i++, j++) {a[i] = tmp[j];}
}
int main(){cin >> n;int *a = new int[n]();for (int i = 0; i < n; ++i) {cin >> a[i];}mergeSort(a, 0, n - 1);for (int i = 0; i < n; ++i) {cout << a[i] << ' ';}return 0;
}

时间复杂度分析:T(n)=2T(n/2)+n

        通过主方法可得T(n)=O(n*logn) 

主方法公式(Master):

测试如下: 

6. 给出快速排序算法,以及快速排序的Partition函数。
//
// Created by GiperHsiue on 2022/10/20.
//
//快速排序
#include <iostream>
using namespace std;
int Partition(int a[], int l, int r){int x = a[l], i = l - 1, j = r + 1;while (i < j){do i++; while (a[i] < x);do j--; while (a[j] > x);if (i < j) swap(a[i], a[j]);}return j;
}
void quickSort(int a[], int l, int r){if (l >= r) return;int q = Partition(a, l, r);quickSort(a, l, q), quickSort(a, q + 1, r);
}int main(){int n;cin >> n;int *a = new int[n];for (int i = 0; i < n; ++i) {cin >> a[i];}quickSort(a, 0, n - 1);for (int i = 0; i < n; ++i) {cout << a[i] << ' ';}return 0;
}

测试如下:

7. 给出分治法设计的循环赛日程表。
//
// Created by GiperHsiue on 2022/10/20.
//
// 循环赛日程表
#include<iostream>
#include<cmath>
using namespace std;void schedule(int k, int n, int** array);int main()
{int k;  // 运动员的人数n=2^kcout << "运动员的人数为n(n=2^k),请输入k的值:";cin >> k;int n = pow(2, k);  // 运动员的人数n=2^kint** array = new int* [n+1]; // 循环赛日程表,动态数组的创建for (int i = 0;i < n+1;i++)array[i] = new int[n+1];// 填充日程表schedule(k, n, array);// 输出日程表cout << "\n循环赛日程表为:\n";for (int i = 1;i <= n;i++){for (int j = 1;j <= n;j++)cout << array[i][j] << " ";cout << "\n";}// 删除二维数组for (int i = 0;i < n + 1;i++)delete[] array[i];delete[] array;return 0;
}void schedule(int k, int n, int** array)   // 数组下标从1开始
{for (int i = 1;i <= n;i++)  // 第一行排1-narray[1][i] = i;int m = 1;  // 用来控制每一次填表时i行j列的起始填充位置for (int s = 1;s <= k;s++)  // k指分成k大部分进行填充日程表;s指第几大部分{n = n / 2;for (int t = 1;t <= n;t++)  // 第s部分内的循环{for (int i = m + 1;i <= 2 * m;i++) // 行{for (int j = m + 1;j <= 2 * m;j++) // 列{array[i][j + (t - 1) * m * 2] = array[i - m][j + (t - 1) * m * 2 - m];       //左上角等于右下角的值array[i][j + (t - 1) * m * 2 - m] = array[i - m][j + (t - 1) * m * 2];       //左下角等于右上角的值}}}m *= 2;}
}

测试如下:

8. 用分治法写出有序序列进行二分查找的过程。
//
// Created by GiperHsiue on 2022/10/20.
//
//二分查找,给出过程
#include <iostream>
using namespace std;
int t = 1;
int BinSearch(int a[], int l, int r, int k){int mid = 0;if(l <= r){mid = (l + r) / 2;cout << "第" << t++ << "次比较:" << " mid = " << mid << " a[mid] = " << a[mid] << endl;if (a[mid] == k) return mid;else if (a[mid] < k) return BinSearch(a, mid + 1, r, k);else return BinSearch(a, l, mid - 1, k);}return -1;
}
int main(){int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, k;for(auto x:a) cout << x << ' ';cout << endl;cin >> k;int res = BinSearch(a, 0, 9, k);cout << "查找结果位置下标:" << res;return 0;
}

测试如下:

9. 对给定的含有n个元素的无序序列,求这个元素中第K小的元素。

法1,可以利用快排思想,在快速排序基础上,在每次划分以后,判定所找元素在哪一边,再只对所在一半继续递归进行划分,直到找到确定位置返回。

法2如下;

//
// Created by GiperHsiue on 2022/10/20.
//
// 对给定的含有n个元素的无序序列,求这个序列中第k小的元素。
// 
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int select(int a[], int start, int end, int k) {int n = end - start;if (n < 5) {sort(a + start, a + end);return a[start + k - 1];}int s = n / 5;int *m = new int[s];   //中位数数组int i;for (i = 0; i < s; i++) {sort(a + start + i * 5, a + start + i * 5 + 5);m[i] = a[start + i * 5 + 2];}sort(m, m + i);int mid = m[i / 2];int *a1 = new int[n];int *a2 = new int[n];int *a3 = new int[n];int num1 = 0, num2 = 0, num3 = 0;for (int i = start; i < end; i++) {if (a[i] < mid)a1[num1++] = a[i];else if (a[i] == mid)a2[num2++] = a[i];elsea3[num3++] = a[i];}if (num1 >= k)return select(a1, 0, num1, k);if (num1 + num2 >= k)return mid;elsereturn select(a3, 0, num3, k - num1 - num2);
}int main() {int n;cout << "输入个数n:";cin >> n;int *a = new int[n];cout << "输入数组元素:";for (int i = 0; i < n; i++)cin >> a[i];int k;cout << "输入所求第几小元素k:";cin >> k;cout << "第" << k << "小元素为:" << select(a, 0, n, k) << endl;delete[] a;return 0;
}

测试如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/578275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArkUI动画概述

目录 1、按照页面分类 2、按照功能分类 3、显示动画 4、属性动画 动画的原理是在一个时间段内&#xff0c;多次改变UI外观&#xff0c;由于人眼会产生视觉暂留&#xff0c;所以最终看到的就是一个“连续”的动画。UI的一次改变称为一个动画帧&#xff0c;对应一次屏幕刷新&a…

一开始我还不信!高德导航红绿灯竟然能读秒?

高德导航红绿灯为啥能读秒&#xff1f; 1 内部员工吐露 每天工作其实就是负责自己片区的红绿灯&#xff0c;一大早就去校对时间&#xff0c;然后发布到后台。是的&#xff0c;统计出来的&#xff0c;而且还是人工统计&#xff0c;有误差请见谅[害羞] 真的是很辛苦了&#xf…

如何使用队列处理 API 速率限制

对于遇到速率限制的应用程序来说也是一个挑战&#xff0c;因为它需要“放慢速度”或暂停。这是一个典型的场景&#xff1a; 初始请求&#xff1a;当应用程序发起与 API 的通信时&#xff0c;它会请求特定的数据或功能。API 响应&#xff1a; API 处理请求并响应请求的信息或执…

12.25

led.c #include "led.h" void all_led_init() {RCC_GPIO | (0X3<<4);//时钟使能GPIOE_MODER &(~(0X3<<20));//设置PE10输出GPIOE_MODER | (0X1<<20);//设置PE10为推挽输出GPIOE_OTYPER &(~(0x1<<10));//PE10为低速输出GPIOE_OSPEED…

单集群400TB,OceanBase稳定支撑快手核心业务场景

一款日均超过千万人访问的短视频 App 快手&#xff0c;面对高并发流量如何及时有效地处理用户请求&#xff1f;通过在后端配置多套 MySQL 集群来支撑高流量访问&#xff0c;以解决大数据量存储和性能问题&#xff0c;这种传统的 MySQL 分库分表方案有何问题&#xff1f;快手对分…

评估回馈电子负载的重要指标?

回馈电子负载是用于测试电源、电池和其他电子设备性能的设备。它可以模拟实际负载&#xff0c;同时将多余的能量回馈到电网或电池中。在选择和使用回馈电子负载时&#xff0c;有几个重要的指标需要考虑&#xff1a; 功率范围&#xff1a;回馈电子负载的功率范围是指其能够提供的…

巅峰画师Midjourney:新时代的独角兽

介绍 AI绘画领域中&#xff0c;Midjourney处于绝对地位&#xff0c;并且一年时间就登顶。 Midjourney是一家独立的AI研究实验室,探索新的思维媒介,拓展人类的想象力。 它由一个小型的自筹资金团队组成,专注于设计、人类基础设施和AI。 在AI绘画领域,Midjourney取得了非常突出…

百度Apollo五步入门自动驾驶:Dreamview与离线数据包分析(文末赠送apollo周边)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 粉丝福利活动 ✅参与方式&#xff1a;通过连接报名观看课程&#xff0c;即可免费获取精美周边 ⛳️活动链接&#xf…

【PDF密码】 一键强制去掉pdf密码

想要给PDF文件设置一个密码防止他人对文件进行编辑&#xff0c;那么我们可以对PDF文件设置限制编辑&#xff0c;设置方法很简单&#xff0c;我们在PDF编辑器中点击文件 – 属性 – 安全&#xff0c;在权限下拉框中选中【密码保护】 然后在密码保护界面中&#xff0c;我们勾选【…

通过three.js玩转车展项目

1.项目搭建 1.1 创建文件夹 mkdir 文件名1.2 初始化package.json npm init -y1.3 安装打包工具并配置相关依赖 npm i parcel -d在package.json中打包路径和指令 1.4 安装three.js npm i three -d2.项目搭建 2.1 新建index.html&#xff0c;并再index.html引入car.js,在…

从流星雨启程:Python和Pygame下载与安装全过程

文章目录 一、前言二、下载安装过程1.官网下载安装包2.安装python过程第一步第二步第三步第四步第五步安装完成 3.简单测试Python3.1 检查 Python 版本号3.2 打开 Python 解释器3.3 输入你的第一个代码3.4 运行 Python 脚本 4.安装Pygame4.1 cmd命令安装Pygame4.2 pip升级4.3 安…

实战:朴素贝叶斯文本分类器搭建与性能评估

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

Java 快速入门

简介 跨平台性&#xff1a;Java 最大的优势之一就是跨平台性&#xff0c;即一份 Java 程序可以在多平台上运行&#xff0c;而无需重写。 简单易学&#xff1a;Java 的语法和面向对象的开发方式非常简单易学。 安全性&#xff1a;Java 对于安全性的处理非常慎重&#xff0c;对…

接口测试和功能测试

本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什么要做&#xff1f; 第二部分&#xf…

wifi驱动打开双模式

双模式 3.1 开启双模式 在Makefile添加EXTRA_CFLAGS -DCONFIG_CONCURRENT_MODE 重新编译&#xff08;make之后发现不正常工作&#xff0c;需要make clean清理一下&#xff09;。 再用sudo rmmod 8821cu.ko&#xff0c;重新启动。出现wlan1&#xff1a; 出现问题&#xff1…

助力打造清洁环境,基于轻量级DETR(DEtectionTRansformer)开发构建公共场景下垃圾堆放垃圾桶溢出检测识别系统

公共社区环境生活垃圾基本上是我们每个人每天几乎都无法避免的一个问题&#xff0c;公共环境下垃圾投放点都会有固定的值班时间&#xff0c;但是考虑到实际扔垃圾的无规律性&#xff0c;往往会出现在无人值守的时段内垃圾堆放垃圾桶溢出等问题&#xff0c;有些容易扩散的垃圾比…

2024年PMP考试新考纲-PMBOK第七版-项目绩效域真题解析

如何一次性通过PMP考试&#xff0c;取得3A等级的PMP证书&#xff1f;华研荟根据十多年的培训和辅导&#xff0c;以及数千名学员的建议是&#xff1a; 先把PMBOK第六版、第七版和敏捷实践指南的三本官方教材研读一遍&#xff08;如果觉得自己看书慢&#xff0c;可以看讲解视频&…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)Dispatcher模块的实现思路和定义

&#xff08;四&#xff09;Dispatcher模块的实现思路 关于dispatcher&#xff0c;它应该是反应堆模型里边的核心组成部分&#xff0c;因为如果说这个反应堆模型里边有事件需要处理&#xff0c;或者说有事件需要检测&#xff0c;那么是需要通过这个poll、epoll 或者 select来完…

Spring Boot3 Web开发技术

前期回顾 springboot项目常见的配置文件类型有哪些&#xff1f;哪种类型的优先级最高 yml properties yaml 读取配置文件里的数据用什么注解&#xff1f; value restful风格 RESTful 风格与传统的 HTTP 请求方式相比&#xff0c;更加简洁&#xff0c;安全&#xff0c;能隐…

Kind创建k8s - JAVA操作控制

kind 简介kind 架构安装 Kind (必备工具)docker官网kubectl官网kind官网校验安装结果 关于kind 命令 安装一个集群查看当前 Kubernetes 集群中的节点信息。查看当前命名空间下中的Pod&#xff08;容器实例&#xff09;的信息。使用 kind create cluster 安装&#xff0c;关于安…