常见算法设计与分析的简单C++代码实现(排列、二分法搜索、Dijkstra算法、元素换位、单调子序列、硬币问题、运动员最佳匹配问题)

news2024/11/18 2:40:04

常见算法设计与分析的简单C++代码实现(排列、二分法搜索、Dijkstra算法、元素换位、单调子序列、硬币问题、运动员最佳匹配问题)

  • 1 一些简单排列问题
  • 2 二分法查找
  • 3 前后元素换位
  • 4 找最长单调递增子序列(O(n2)复杂度)
  • 5最小硬币问题
    • 一、问题描述:
    • 二、实现目标:
    • 三、 算法设计:
    • 四、数据输入:
    • 五、结果输出:
    • 代码附录
  • 6 Dijkstra算法实现
  • 7运动员最佳配对问题
    • 一、问题描述
    • 二、算法设计
    • 三、数据输入
    • 四、结果输出及具体实现

Author(作者): Nirvana Of Phoenixl
*Proverbs for you(送给你的哦):There is no doubt that good things will always come, and when it comes late, it can be a surprise.如有转载请注明,谢谢!

1 一些简单排列问题

要求:求一组数的最大值,实现功能任意输入数字计算出其最大值,代码详情见附录:

实现过程截图如下图所示:

(1)输入数组直接求解最大值实现截图,如图1所示,完整实现代码详情见附录1:

在这里插入图片描述
​              图1 求数组最大值

附录1#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int max_n(int n, int num[]);
int max_2(int a, int b);
int main()
{
	int max;
	int num[4];
	printf("Please input 4 numbers:");
	scanf("%d %d %d %d", &num[0], &num[1], &num[2], &num[3]);
	max = max_n(4, num);
	printf("%d", max);
}
int max_n(int n, int num[])
{
	int max;
	if (n > 2)
		max = max_2(num[n - 1], max_n(n - 1, num));
	if (n == 2)
		max = max_2(num[n - 2], num[n - 1]);
	return max;
}
int max_2(int a, int b)
{
	return (a > b ? a : b);
}

(2)利用递归法求最大值,如图2所示,限制数组长度,实现求解最大值截图,完整实现代码详情见附录2:
在这里插入图片描述
​          图2 递归法限制数组长度求最大值

附录2:

#include<iostream>
using namespace std;


int maxTea(int a[], int n) {
	int max = a[0];
	for (int j = 1; j < n; j++) 
	{
		if (a[j] > max) 
		{
			max = a[j];
		}
	}
	return max;
}


int main() {
	int n;
	int a[200];
	printf("请输入数组长度并回车输入数字:");
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}

	int count = maxTea(a, n);
	cout << count << endl;
	return 0;
}

(3) 实现全排列问题(实现对输入任意数的全排列)

实现过程截图如图3所示,完整实现代码详情见附录3:

在这里插入图片描述
​              图3 任意输入数全排列实现

附录3:

#include<cstdio>

int count = 0;

void myswap(int& a, int& b)
{
	int t = a; a = b; b = t;
}

//对数组p下标为m到n-1的元素进行全排列
void perm(int* p, int m, int n)
{
	if (m == n - 1)
	{
		count++;
		for (int i = 0; i < n; i++)
			printf("%d ", p[i]);
		printf("\n");
	}
	for (int i = m; i < n; i++)
	{
		if (i == m)//i == m时无需交换p[i]和p[m]的值
			perm(p, m + 1, n);
		else
		{
			myswap(p[i], p[m]);
			perm(p, m + 1, n);
			myswap(p[i], p[m]);
		}
	}
}

int main()
{
	int p[50];
	int n = 0;
	printf("请输入待排列的数字,空格隔开,回车结束:");
	do
	{
		scanf_s("%d", &p[n++]);
	} while (getchar() != '\n');
	perm(p, 0, n);
	printf("%d个全排列\n", count);
	return 0;
}

2 二分法查找

​ 设a[0:n-1]是已排好序的数组。请改写二分搜索算法,使得当前搜索元素x不在数组中时,返回值小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,ij相同,均为x数组中的位置。实现过程部分截图如下所示:

​ (1)当x属于a[0:n-1]时,ij均返回x元素的位置,如图1所示:
在这里插入图片描述
​                  图1 x属于数组a[]

附录代码:

#include<stdio.h>
#include<stdlib.h>

//二分法查找
int search(int a[], int length, int x)       //a是搜索数组,x为搜索元素
{
	int i = 0, j = 0;
	int detection = -1;                 //标志位
	int top = length - 1;                // 数组的右边界
	int middle = 0;                    //中间值的下标
	int low = 0;                      //数组的左边界

	while (low <= top)
	{
		middle = (low + top) / 2;
		if (a[middle] == x)
		{
			detection = middle;
		}
		if (a[middle] < x)
		{
			low = middle + 1;
		}
		else
		{
			top = middle - 1;
		}
	}
	if (detection == -1)
	{
		//如果x没有在其中,则执行完,top为底,low为顶,x在中间。
		i = top;
		j = low;
	}
	else
	{
		i = detection;
		j = i;
	}
	printf("i的值为:%d\nj的值为:%d\n", i, j);
	return 0;
}

void main()
{
	int arr[] = { 10,20,30,40,50,60,70,80,90,100,110 };
	int length = sizeof(arr) / sizeof(int);
	search(arr, length, 92);
	system("pause");
}

​ (2) 当x不属于a[0:n-1]时,返回值小于x的最大元素位置i和大于x的最小元素位置j,如图2所示:

在这里插入图片描述
​                  图2 x不属于数组a[]

3 前后元素换位

​ 设a[0:n-1]是有n个元素的数组,k是一个非负整数。试着设计一个算法将子数组a[0:k-1]与a[k:n-1]换位。要求算法在最坏的情况下耗时O(n),且只用到O(1)的辅助空间。实现过程部分截图如图3所示:

在这里插入图片描述
​                  图3 数据交换

代码附录:

#pragma warning(disable:4996)// 解决报错
#include <stdio.h>
#include <stdlib.h>

void Swap(int * a, int left, int right) {
	//交换数组left到right的内容  
	for (; left < right; left++, right--) {
		int t = a[left];
		a[left] = a[right];
		a[right] = t;
	}
}
void SwapArray(int * a, int array_size, int x) {
	//首先交换第一个子数组的内容  
	Swap(a, 0, x);
	//再交换第二个子数组的内容  
	Swap(a, x + 1, array_size - 1);
	//交换整个数组的元素  
	Swap(a, 0, array_size - 1);
}
int main() {
	int x, i, n;
	printf("请输入数组长度:\n");
	scanf("%d", &n);
	printf("请输入数组元素:");
	int * a = (int *)malloc(sizeof(int)*n);
	for (i = 0; i < n; i++)	scanf("%d", &a[i]);
	printf("请输入交换位置:");
	scanf("%d", &x);
	SwapArray(a, n, x);
	for (i = 0; i < n; i++) {
		printf("%d ", a[i]);
	}
	printf("\n");
	free(a);
}

4 找最长单调递增子序列(O(n2)复杂度)

​ 设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

​ 实现过程及主要步骤:

​ 1.输入一个序列a[]

​ 2.将该序列进行排序得到新的序列b[](递增序列)

​ 3.将问题转化为求这两个序列a,b的最大公共子序列

​ 4.运用动态规划的解题思想,先求得子问题的结果,记录在c[][]数组中,再根据c[][]中的值的情况得到最大公共子序列。

在这里插入图片描述

(代码见如下)

#include<stdio.h>
int main() 
{
	int max = 0, count = 1, n = 15;
	int b, c;
	int a[] = { 2,9,1,4,7,8,14,32,36,38,17,20,36,41,24 };   //定义原始数组序列长度为15
	for (int i = 0; i < n; i++) 
	{
		b = a[i];                                 //取a中的数据存入暂b用以比较存较大的
		for (int j = i + 1; j < n; j++) 
		{
			if (b < a[j]) {
				b = a[j];
				count++;
			}
			else break;
		}
		if (max < count)                                  //更新计数值
		{                                               //不连续大于,继续用当前元素排
			max = count;
			c = i;
		}
		count = 1;
	}
	printf("%d ", a[c]);
	b = a[c];                                       //输出此时的元素作为第一个递增元素 
	for (int i = c + 1; i < n; i++) 
	{
		if (b < a[i]) {
			b = a[i];
			printf("%d ", b);
		}
		else break;
	}
	return 0;
}

5最小硬币问题

一、问题描述:

设有n种不同面值的硬币,各硬币的面值存于数组T[1:n]中。现要用这些面值的硬币来找零钱。可以使用的各种面值的硬币个数存于数组Coins[1:n]中。

二、实现目标:

对任意钱数0≤m≤20001,设计一个用最少硬币找钱m的方法。

三、 算法设计:

对于给定的1≤n≤10,硬币面值数组T和可以使用的各种面值的硬币个数数组Coins,以及钱数m,0≤m≤20001,计算找钱m的最少硬币数。

四、数据输入:

由文件input.txt提供输入数据,文件的第1行中只有1个整数给出n的值,第二行起每一行2个数,分别是T[j]和Coins[j]。最后一行是要找的钱数m。

五、结果输出:

将计算出的最少硬币数输出到文件output.txt。问题无解时输出-1。

在这里插入图片描述
​          输出成功钱数m(18)对应最小硬币数

在这里插入图片描述
​            问题无解输出-1

实现过程截图:(具体代码实现详解见附录)

代码附录


#include <stdio.h>
#include <iostream>                   
using namespace std;                
                                 // cout<<a<<endl; 相当于printf("%d\n", a)

int Coins[11], T[11], a[20001];   //coins表示各硬币面值个数,T表示硬币面值,a表示钱数;
int i;

int min(int a, int b)                     
{
	if (a < b)
		return a;
	else
		return b;
}

int main()
{
	int n, m;
	cout << "输入硬币的面值种数:";     // 加载cout是一个iostream类的对象,向输出设备
	cin >> n;     //标准输入函数cin 它是代表标准的输入设备--键盘,也就是:cin >> 变量;
                                //输入多个变量可以写在一行,如:cin >> x >> y >> z;
	

	cout << "\n输入硬币面值和此面值硬币个数:" << endl;
	for (int i = 0; i < n; i++)           //按照输入数面值数n,依次输入面值和数量
	{
		cin >> Coins[i] >> T[i];
	}

	cout << "请输入要找的钱数:";
	cin >> m;                           //输入钱数m

	for (i = 1; i <= m; i++)
		a[i] = 99999;

	for (i = 0; i < n; i++)           // 在所有面值种类内循环,共计n种面值
	{
		for (int j = 1; j <= T[i]; j++) //从硬币面值数组中,依次取用所有面值硬币
		{
			for (int k = m; k >= Coins[i]; k--) //按照钱数m,从该面值对应的硬币数量中取
			{
				a[k] = min(a[k], a[k - Coins[i]] + 1);//
			}
		}
	}
	cout << "最少硬币个数:";
	cout << (a[m] < m ? a[m] : -1) << endl;
}

	cout << "最少硬币个数:";
	cout << (a[m] < m ? a[m] : -1) << endl;
}

6 Dijkstra算法实现

点击这里_Dijkstra算法实现

本文由关于该算法的分析及实现,可以作为参考!

7运动员最佳配对问题

一、问题描述

​ 羽毛球队员有男女运动员各n人。给定2个n×n矩阵P和Q。P[i][j]是男运动员i和女运动员j配对组合成混合双打的男运动员竞赛优势;Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势。由于技术配合和心理状态等各种因素影响,P[i][j]不一定等于Q[j][i]。男运动员i和女运动员j配合组成混合双打的男女双方竞赛优势为P[i][j]*P[j][i]。设计一个算法,计算男女运动员最佳配对方法,使得各组男女双方竞赛优势的总和达到最大。

二、算法设计

​ 设计一个算法,对于给定的男女运动员竞赛优势,计算男女运动员最佳配对法,使得各组男女双方竞赛优势的总和达到最大。

三、数据输入

​ 由文件input.txt给出输入数据。第一行有1个正整数n。接下来的2n行,每行n个数;前n行是p,后n行是q。

四、结果输出及具体实现

​ 将计算的男女双方竞赛优势的总和的最大值输出到文件output.txt。
在这里插入图片描述

​ 分析:对于给定的n来说,我们先确定男生的配对顺序是不变的,比如1,2,3等,从第1个男运动员开始搭配女运动员:第1个有n种搭配方法,第2个有n-1种搭配方法……第n个有n-(n-1)种搭配方法;根据问题给出的示例:输入n的值为3,表示男女运动员各有3名;

​ (1)根据男运动员A(1)、B(2)、C(3)按顺序搭配女运动员,他们分别对应的女运动员可以是:女运动员分别为1 2 3、1 3 2、2 1 3、2 3 1、3 1 2、3 2 1。

​ (2)确定该配对问题的解空间是{(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)},整个问题可看成是1,2,3的全排列问题,将解空间组织成一棵排列树。

​ 实现截图如下,代码实现见附录:
在这里插入图片描述

附录:

#include <iostream>
using namespace std;

int n, m[20][20], w[20][20]; // n表示男女生个数、用m表示男生,w表示女生

int sum = 0, a[20]; // sum表示配对总分数,a存入输入的男女运动员数

void Backtrack(int t) {
	if (t > n) {            //递归结束判定条件
		int temp = 0;
		for (int i = 0; i < n; i++) {
			temp += m[a[i]][i] * w[i][a[i]];  //计算
		}
		if (temp > sum) {
			sum = temp;
		}
	}
	else {
		for (int i = t; i <= n; i++) {
			int temp = a[i - 1];
			a[i - 1] = a[t - 1];
			a[t - 1] = temp;
			Backtrack(t + 1);
			temp = a[i - 1];
			a[i - 1] = a[t - 1];
			a[t - 1] = temp;
		}
	}
}

int main() {
	cout << "请输入男女运动员个数(<20):";
	cin >> n;
	for (int i = 0; i < n; i++) {
		a[i] = i;
	}
	for (int i = 0; i < n; i++) {
		cout << "请输入男运动员配对女运动员P的优势:";
		for (int j = 0; j < n; j++) {
			cin >> m[i][j];
		}
	}
	for (int i = 0; i < n; i++) {
		cout << "请输入女运动员配对男运动员Q的优势:";
		for (int j = 0; j < n; j++) {
			cin >> w[i][j];
		}
	}
	Backtrack(1);
	cout << "--------";
	cout << "男女双方竞赛优势最大为:";
	cout << sum;
	return 0;
}

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

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

相关文章

c3p0,DBCP,Druid(德鲁伊)数据库连接池

c3p0&#xff0c;DBCP&#xff0c;Druid&#xff08;德鲁伊&#xff09;数据库连接池 每博一文案 佛说&#xff1a;前世 500 次的回眸&#xff0c;才换来今生的一次擦肩而过。 人与人之间的缘分&#xff0c;真的无需强求&#xff0c;并不是所有的感情都能天长地久&#xff0c;…

C#压缩图片

SqlSer数据库设置保存图片字段类型为Image类型 对应保存 方法参数为图片路径&#xff0c;压缩后路径&#xff0c;压缩最大宽度&#xff0c;压缩最大高度 引用类型using System.Data; using System.Drawing; using System.IO; \完整类 /// <summary> /// 按比例缩放&…

七牛qshell 批量上传 mac 本地目录

七牛qshell 批量上传 mac 本地目录下载路径及使用方法(官方)下载到自己指定的文件夹添加环境变量,使qshell在任意地方可以执行添加密钥 生成账户文件下载路径及使用方法(官方) https://developer.qiniu.com/kodo/1302/qshell记录自己部署遇到的问题及操作步骤 下载到自己指定…

音视频开发核心知识点及源码解析,还不赶紧收藏起来

随着基础设施的完善&#xff08;光纤入户、wifi覆盖、5G普及&#xff09;的影响&#xff0c;将短视频、直播、视频会议、在线教育、在线医疗瞬间推到了顶峰&#xff0c;人们对音视频的需求和要求也越来越强烈 音视频开发还具有许多方向&#xff0c;比如&#xff1a; 如果对音视…

C语言:while后加分号与for后加分号的区别

while 后面不能加分号&#xff0c;否则虽然编译可以通过&#xff0c;但是执行程序时会发生死循环#include <stdio.h> int main() { int i1,total0; while(i<100)//不能在 while 后面加分号 { totali; i;//循环…

个人付费专栏上线预热

个人付费专栏上线预热 专栏地址&#xff1a;请点击访问 文章目录一、订阅这个专栏有什么好处&#xff1f;二、实战项目预告1. 活动类站点 &#xff08;已完成前端后端&#xff09;2. 电商项目 &#xff08;筹备中&#xff0c;一比一还原设计图&#xff09;3. 论坛问答系统 &…

每日三题-爬楼梯、买卖股票的最佳时机、正则表达式匹配

&#x1f468;‍&#x1f4bb;个人主页&#xff1a; 才疏学浅的木子 &#x1f647;‍♂️ 本人也在学习阶段如若发现问题&#xff0c;请告知非常感谢 &#x1f647;‍♂️ &#x1f4d2; 本文来自专栏&#xff1a; 算法 &#x1f308; 算法类型&#xff1a;Hot100题 &#x1f3…

IP 摄像机移动应用 SDK 开发入门教程(安卓版)

涂鸦智能安卓版摄像机&#xff08;IP Camera&#xff0c;简称 IPC&#xff09;SDK 是基于智能生活 App SDK 开发而成。 通过移动应用控制物理网设备是常见的使用场景&#xff0c;但由于设备的品类丰富&#xff0c;增大了应用开发难度。因此 智能生活 App SDK 提供了常见的垂直…

支付宝支付内网穿透

支付宝支付&内网穿透一 沙箱环境二 python第三方模块python-alipay-sdk三 python-alipay-sdk二次封装四 支付接口五 内网穿透5.1 cpolar软件5.2 测试支付宝post回调一 沙箱环境 注册认证沙箱环境&#xff1a;https://openhome.alipay.com/platform/appDaily.htm?tabinfo …

【FileZila】实现windows与Linux系统文件互传

1、下载安装FileZila客户端 根据自己的PC系统版本&#xff0c;下载对应的FileZila客户端https://www.filezilla.cn/download/client 2、Linux服务端&#xff0c;安装配置vsftpd 2.1 安装ftp服务 sudo apt-get install vsftpd2.2 配置ftp服务 &#xff08;1&#xff09;打开ft…

Verilog 实现CDC中单bit 跨时钟域,从慢时钟域到快时钟域

单bit 跨时钟域&#xff0c;从慢时钟域到快时钟域1&#xff0c;首先&#xff0c;了解一些问题2&#xff0c;RTL代码设计3&#xff0c;testbench测试代码4&#xff0c;RTL代码和testbench综合的电路原理图5&#xff0c;前仿真&#xff0c;验证![在这里插入图片描述](https://img…

关于某些地区延期举办2022年11月27日 PMI认证考试等有关事项的通知

22年.11月22日通知&#xff1a; 关于成都等六个地区延期举办2022年11月27日 PMI认证考试等有关事项的通知 尊敬的考生&#xff1a; 受近日疫情影响&#xff0c;结合当地疫情防控规定和活动举办要求&#xff0c;成都、武汉、西安、昆明、银川、长春地区现不满足组织2022年11月…

A. The Enchanted Forest(思维)

Problem - 1687A - Codeforces 玛丽莎来到魔法森林采摘蘑菇。 魔法森林可以用X轴上编号为1到n的n个点来表示。在玛丽莎开始之前&#xff0c;她的朋友帕秋莉用魔法检测了每个点上的蘑菇的初始数量&#xff0c;用a1,a2,...,an表示。 玛丽莎可以在第0分钟时从森林的任何一点开始…

Allegro如何输出IDF文件操作指导

Allegro如何输出IDF文件操作指导 Allegro支持输出IDF文件,用于导入结构软件中检查和查看,具体操作如下 点击File-export-IDF 会弹出一个对话框,file name type选择IDF 然后点击export,输出IDF文件,文件已经输出 This section is describe what the function allegro h…

项目管理工具需要具备的五点功能

将新产品推向市场是有益的&#xff0c;但也具有挑战性。从一个概念到成功发布的过程涉及很多事情。在产品开发过程中&#xff0c;许多内部团队都参与了将概念推向市场的工作。例如&#xff0c;设计团队、工程团队和营销团队都在这个生命周期中发挥作用。协调时间表、阶段和可交…

【Vue】组件化和声明周期函数

1. 组件化 组件化就是指一个后台我们将它的各个部分拆分成各个组件&#xff0c;比如 csdn 的上边栏、右侧广告区等都可以是组件&#xff0c;组件可以复用。Vue 的一个好处就是组件化。 <!DOCTYPE html> <html lang"en"> <head><meta charset&…

【云原生】Docker的数据卷、数据卷容器,容器互联

内容预知 1.数据卷&#xff08;容器与宿主机之间数据共享&#xff09; 2. 数据卷容器&#xff08;容器与容器之间数据共享&#xff09; 3. 容器互联&#xff08;使用centos镜像&#xff09; 3.1 实现容器互联 3.2 只通过IP进行通信 总结 1.数据卷&#xff08;容器与宿主…

视频编解码 - 帧间预测

目录 帧间预测 块大小 参考帧和运动矢量 运动矢量 运动搜索 1、全搜索算法 2、钻石搜索算法&#xff08;菱形搜索算法&#xff09; 3、六边形搜索算法 搜索起始点的确定 快速搜索与全搜索的优缺点 非整像素的处理 亚像素差值 亚像素精度运动搜索 运动矢量预测 S…

双十二蓝牙耳机哪款好?双十二平价蓝牙耳机推荐

对于许多人来说&#xff0c;音乐即是生活良药&#xff0c;带给我们生活、工作和学习的动力&#xff0c;若想要随时随地都能来上一剂&#xff0c;那么买到一款划算平价的真无线蓝牙耳机便是优秀的选择。 一、南卡小音舱蓝牙耳机 蓝牙&#xff1a;5.3 延迟&#xff1a;45ms 发…

npm、yarn到pnpm的发展历程

npm、yarn到pnpm的发展历程背景价值点npm发展及存在的问题npm v1&#xff08;树状结构&#xff09;安装原则优点不足&#xff1a;npm v3&#xff08;扁平化结构&#xff09;安装原则优点&#xff1a;不足&#xff1a;目录结构不确定依赖A先安装依赖A后安装npm v5优点npm包分身定…