第二站:分支与循环(终幕)一些经典的题目

news2024/12/25 12:51:53

目录

一、计算n的阶乘

1.一般解法

2.优化不能表示出较大数的阶乘

二、 计算 1!+2!+3!+……+10!

1.循环嵌套解法

 2.一次循环解法(优化计算时间)

三、在一个有序数组中查找具体的某个数字n

1.遍历查找

2.二分查找算法(优化了查找时间)

四、编写代码,演示多个字符从两端移动,向中间汇聚。

1.一般解法

2.优化后的解法(提高用户体验感)

五、编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序。)

1.一个经典的错误,标准的零分

六、求最大公约数

1.一般解法

2.辗转相除法


一、计算n的阶乘

1.一般解法

这道题目比较简单,下面就是我们的代码实现

#include<stdio.h>
int main()
{
	int i, ret = 1;
	int n;
	scanf("%d", &n);
	for (i = 1; i <=n; i++)
	{
		ret = ret * i;
	}
	printf("%d", ret);
}

但是我们说这还不够。因为如果我们输入的数据比较大,就很可能会发生溢出,因为int类型最多有32个比特位,也就是最大能表示2的三十二次方的大小,那么如何表达更大类型的数呢,答案是将int改为double,这样最大就可以表示2的64次方的大小了。

2.优化不能表示出较大数的阶乘

#include<stdio.h>
int main()
{
	int i;
	double ret = 1;
	int n;
	scanf("%d", &n);
	for (i = 1; i <=n; i++)
	{
		ret = ret * i;
	}
	printf("%.0f", ret);
}

计算 1!+2!+3!+……+10!

1.循环嵌套解法

这道题是第一题的一个拓展。既然我们已经有了第一道题的基础,这第二道题相信大家也应该有思路,那便是循环嵌套一层。下面是代码实现

#include<stdio.h>
int main()
{
	int i, j;
	int ret = 1;
	int sum = 0;
	for (i = 1; i <= 10; i++)
	{
		ret = 1;
		for (j = 1; j <= i; j++)
		{
			ret = ret * j;
		}
		sum = sum + ret;
	}
	printf("%d", sum);
	return 0;
}

这样确实是实现了我们的代码,但是我们说这还不够好,因为效率太低,试想一下,如果这个数很大呢,让加到100,1000呢,那这些阶乘运算中出现了大量的重复性计算,使得我们的计算出答案所需的时间增加,所以为了优化,我们可以只需使用一次for循环就可以得出答案。

 2.一次循环解法(优化计算时间)

#include<stdio.h>
int main()
{
	int i;
	int ret = 1;
	int sum = 0;
	for (i = 1; i <= 3; i++)
	{
		ret = ret * i;
		sum = sum + ret;
	}
	printf("%d", sum);
	return 0;
}

这样的话,我们的时间复杂度也大大降低。时间复杂度的概念将在以后的文章中详细讲到。这里读者暂时不用深究。

三、在一个有序数组中查找具体的某个数字n

1.遍历查找

比如说我们在一个从1--10的数组中找出7,最简单的方法当然是遍历了,代码实现如下

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;//要找它
	int i;
	int flag = 0;
	for (i = 0; i < 10; i++)
	{
		if (arr[i] == k)
		{
			printf("找到了,下标是%d",i);
			flag = 1;
			break;
		}
	}
	if (flag == 0) 
	{
		printf("找不到");
	}
	return 0;
}

但是,这效率太低了,因为我们最坏要找n次,n为数组的个数。那么有没有什么更高效的方法呢?我们说,是有的,接下来给大家介绍一个二分查找算法,也叫折半查找算法。

2.二分查找算法(优化了查找时间)

如下图所示,这是一个数组,如果我们想找到7这个元素,如何找呢?

 首先我们先确定左下标和右下标,方便我们知道查找到了那个位置,此时我们所查找的范围为[left,right]这个闭区间,如下图所示

 紧接着,我们引入一个中间量mid作为一个下标,mid这个数组下标为左下标与右下标之和除以2,取出商的部分,忽略掉余数。即mid=(left+right)/2,如下图所示,为第一次二分。

 查找之后我们发现,arr[mid]<7,也就是说,7在arr[mid]的右侧,所以此时[left,mid]这个闭区间就不在我们的查找范围内了,我们新的查找范围为(mid,right]这个左开右闭区间,为了和前面统一,都为闭区间,我们不妨令新的区间为[mid+1,right]这个闭区间。在这个闭区间上,我们令left=mid+1,这样我们要查找的闭区间为[left,right]了,这样一来,我们就会发现,这好像可以用一个循环,通过一个循环,让它来一直执行下去,我们就能很高效的找出所需要查找的闭区间了。但是,为了大家更好的理解,我们继续画图往下执行。

上图中,这是我们第二次找出中间值的图解,为图中紫颜色部分,我们发现arr[mid]>7,那说明[mid,right]这个闭区间中没有7,于是我们所需要查找的新区间为[left,mid-1]这个闭区间。我们同样令right=mid-1,这样我们的新的需要查找的区间为[left,right]了

 如上图所示,红色部分为新下标示意图,由于arr[mid]<7,所以根据上面的原理可得,[left+1,right]为新区间。我们继续进行查找。

 如上图所示,此时我们的arr[mid]=7,也就是说找到了,我们就可以返回这个mid,就是我们所找到的下标。

以上就是我们二分查找算法的图解,相信大家都已经看懂了吧,有人说,那么既然这是个循环实现的,那么循环里面的条件应该填什么呢?其实很简单,我们根据上面的图解也能发现,只有left<=right时,也就是说,左下标小于等于右下标时候,因为不可能右下标小于左下标,这样我们的程序才能执行下去,这也就是我们的判断条件。

那么我们将上面的代码实现以下吧

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;//要找它
	int left = 0;
	int right = 9;
	int flag = 0;
	int mid = 0;
	while (left <= right)
	{
		mid = (left + right) / 2;
		if (arr[mid] > k)
		{
			right = right - 1;
		}
		else if (arr[mid] < k)
		{
			left = left + 1;
		}
		else
		{
			printf("找到了,下标为%d", mid);
			flag = 1;
			break;
		}
	}
	if (flag == 0)
	{
		printf("找不到");
	}
	return 0;
}

四、编写代码,演示多个字符从两端移动,向中间汇聚。

1.一般解法

我们先直接给出代码

#include<stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "welcome to world";
	char arr2[] = "****************";
	int left = 0;
	int right = strlen(arr2) - 1;
	while (left <= right)
	{
		
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		left++;
		right--;
	}
	return 0;
}

在这个代码中,我们给出两个字符数组并且进行初始化,arr1是需要被慢慢显现出来的,arr2是需要被打印出来的,以此来展示出效果,我们采用和二分查找类似的思想,使用一个左下标,和一个右下标。我们右下标是直接采用一个库函数strlen计算出来的,因为计算出来的是长度,所以我们需要减1,来代表下标。然后我们逐步将arr1的数组赋值给arr2,并且打印出arr2。然后一直循环,循环条件也与二分查找类似,只需要我的左下标小于等于右下标,我就可以继续执行下去

运行截图为

 但是我们可不可以对它在优化一点呢。比如说我们想要在加上两个需求,一个需求是使得它打印以此,停顿一秒钟,然后继续打印。另外一个需求是,打印一次,清屏一次呢?我们说,是可以的。在这里我们就需要使用到两个库函数了。

2.优化后的解法(提高用户体验感)

Sleep()//作用是休眠,单位是毫秒    需要调用头文件include<window.h>

system("cls") //作用是清屏,需要调用头文件include<stdlib.h>

 以下就是我们最终的代码了。读者可以自行去运行

#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<stdlib.h>
int main()
{
	char arr1[] = "welcome to world";
	char arr2[] = "****************";
	int left = 0;
	int right = strlen(arr2) - 1;
	while (left <= right)
	{
		
		arr2[left] = arr1[left];
		arr2[right] = arr1[right];
		printf("%s\n", arr2);
		left++;
		right--;
		Sleep(1000);
		system("cls");
	}
    printf("%s\n", arr2);
	return 0;
}

五、编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序。

1.一个经典的错误,标准的零分

我们先给出一段代码,并且尝试分析一下,判断是否正确?

#include<stdio.h>
int main()
{
	int i;
	int flag = 0;
	char password[20] = {0};
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:");
		scanf("%s", password);
		if (password == "123456")
		{
			printf("密码正确\n");
			flag = 1;
			break;
		}
		else 
		{
			printf("密码第%d次输入错误\n", i + 1);
		}
	}
	if (flag == 0)
	{
		printf("密码三次输入错误,退出程序");
	}
	return 0;
}

当我们想要输入一个密码时候,我们首先得定义一个字符数组来存放密码。接着我们使用一个循环,用来记录三次密码的上限,在循环中,我们输入密码,然后使用一个if语句来判断,我们直接使用一个==来进行判断,然后如果对,就跳出循环,不对,则继续循环。这个逻辑似乎听着没问题,但是事实真的是这样吗?我们运行一下试试

我输入了123456,居然提示我密码错误?怎么回事?哪里出问题了?其实这里犯了一个经典的错误,标准的零分。我们说,判断两个字符串相等不是这样判断的,这样判断就是经典的错误标准的零分。

那我们应该怎么判断呢?,其实c语言中提供了一个库函数,叫做strcmp(  ,),这个库函数用于比较字符串。

那么如何比较呢?是这样比较的

//判断两个字符串是否相等,不能直接使用==
 int ret = strcmp(password,"123456");
//如果两个字符串相等,则返回0
//如果password小于"123456",也就是第一个字符串小于第二个字符串,则返回小于0的一个数字
//如果password大于"123456",也即是第一个字符串大于第二个字符串,则返回大于0的一个数字

有的人可能有疑惑了,两个字符串咋比较的?是比较他们的长度吗?我们说不是的,字符串的比较是一个一个往下比较的,也就是说,第一个字符串的第一个字符与第二个字符串的第一个字符进行比较,比较的是他们的ASCII值,如果第一位能比较出来谁大,则就是哪个字符串大,如果第一位都相等,则判断两个字符串的第二位,如此循环下去进行判断,直到遇到\0。也就代表着字符串的结束。关于字符串的一些库函数,我们在后面还会更加详细的讲解,读者暂时只需要了解到,我目前所讲解到的即可,注意使用这个库函数需要引用头文件<string.h>

所以最终的代码实现为,

#include<stdio.h>
#include<string.h>
int main()
{
	int i;
	int flag = 0;
	char password[20] = {0};
	for (i = 0; i < 3; i++)
	{
		printf("请输入密码:");
		scanf("%s", password);
		if (0 == strcmp(password, "123456")) 
		{
			printf("密码正确\n");
			flag = 1;
			break;
		}
		else 
		{
			printf("密码第%d次输入错误\n", i + 1);
		}
	}
	if (flag == 0)
	{
		printf("密码三次输入错误,退出程序");
	}
	return 0;
}

六、求最大公约数

1.一般解法

缺点:计算量太过于复杂。

#include<stdio.h>
int main()
{
	int m = 24;
	int n = 18;
	int max = m > n ? m : n;
	while (max>0)
	{
		if (m % max == 0 && n % max == 0)
		{
			printf("%d", max);
			break;
		}
		max--;
	}
	return 0;
}

2.辗转相除法

这种方法不需要掌握原理,因为涉及到数学方面的知识

我们的想法是这样的,m和n这两个数,用m对n取模,并记录结果t,如果结果不为0,则把n给m,t给n,如此循环下去。知道结果为0,最终答案为n

#include<stdio.h>
int main()
{
	int m = 24;
	int n = 18;
	int ret;
	while (m % n != 0)
	{
		ret = m % n;
		m = n;
		n = ret;
	}
	printf("%d", n);
	return 0;
}

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

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

相关文章

IDEA Out of memory 问题

文章目录1. 前提2. 问题记录与解决方案1. 前提 阅读本文之前&#xff0c;读者要首先把 Out of memory 这个问题的解决方案多搜几个帖子&#xff0c;先按照其他帖子的解决方案&#xff08;修改配置文件Xmx属性等&#xff09;尝试一遍&#xff0c;不能解决再参考本文。 本文所描…

前端小游戏——植物大战僵尸

给大家分享一个植物大战僵尸网页游戏源代码&#xff0c;感兴趣的小伙伴可收藏学习 &#x1f449;完整源码 文章目录⌛️效果展示⌛️游戏介绍⌛️游戏内容&#xff08;1&#xff09;冒险模式&#xff08;2&#xff09;小游戏⌛️图片资源⌛️代码展示&#xff08;1&#xff09;…

【黑猩猩算法】基于加权反对技术和贪婪搜索进化黑猩猩优化算法求解多模态工程问题附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

终于拿到了阿里P8架构师分享的JCF和JUC源码分析与实现笔记java岗

时代的一粒尘&#xff0c;落在每个人身上&#xff0c;就是一座山”。 时代更迭变换&#xff0c;我们好像都知道今天与昨天不同&#xff0c;又好像肉眼看不出哪里不同。 但其实它就正在以各种各样的方式体现在每一个普通人身上。 疫情爆发三个月的时间&#xff0c;截止2020年…

~外中断~

目录 一、接口芯片和端口 二、外中断信息 三、PC机键盘的处理过程 一、接口芯片和端口 外设的输出不直接送入内存和CPU&#xff0c;而是送入相关的接口芯片的端口中&#xff1b;CPU向外设的输出也不是直接送入外设&#xff0c;而是先送入端口&#xff0c;再由相关的芯片送到…

C语言程序设计--火车订票系统

任务要求: 创建一个火车票管理系统&#xff0c;功能包括&#xff1a; &#xff08;1&#xff09;录入班次信息(信息用文件保存),可不定时地增加班次数据 &#xff08;2&#xff09;浏览班次信息,可显示出所有班次当前状总(如果当前系统时间超过了某班 次的发车时间,则…

js中map()的使用详解

引入&#xff1a; 有网友有如下困惑&#xff1a; map是数组的方法&#xff0c;有一个参数&#xff0c;参数是一个函数&#xff0c;函数中有3个参数 参数1&#xff1a;item必须。当前元素的值 参数2&#xff1a;index&#xff0c;可选。当前元素在数组中的索引值 参数3&#xff…

CentOS 7迁移Anolis OS 7 ——筑梦之路

迁移注意事项 Anolis OS 7生态上和依赖管理上保持跟CentOS7.x兼容&#xff0c;一键式迁移脚本centos2anolis.py&#xff0c;实现CentOS7.x到Anolis OS 7的平滑迁移。 使用迁移脚本前需要注意如下事项&#xff1a; 迁移涉及到软件包的重新安装&#xff0c;是不可逆过程&#…

BBR/CUBIC 共存时的 buffer 挤兑

BBR 与 CUBIC 共存时的收敛图&#xff0c;理论情况&#xff1a; 理论上 BBR 不会挤占 buffer&#xff0c;inflight 保持为恒定的 BDP。 但 BBR 的 inflight 做不到恒定&#xff0c;多流共存时&#xff0c;依然会 “主动占用 buffer” 而相互挤兑带宽&#xff0c;而该行为是必须…

java - 序列化

钱应该怎么花 前几天看到一个新闻&#xff0c;一女子打拼了5年攒了30万买房钱&#xff0c;最后因为意外被一场突如其来的大火烧了&#xff0c;经过多家银行&#xff0c;长达4小时的鉴定&#xff0c;挽回了15万损失。 还看到一个新闻&#xff0c;老人攒5000元钱遭虫蛀烂&#…

「Linux」400行纯C语言代码带你「手撕线程池」

线程池的基本概念 不管线程池是什么东西&#xff01;但是我们必须知道线程池被搞出来的目的就是&#xff1a;提高程序执行效率而设计出来的&#xff1b; 了解了线程池的目的后&#xff1a;我们就可以开始理解线程池&#xff1a; 首先回答一个问题&#xff1a;为什么会有线程…

python文件的读取

python文件的读取1.文件的读取1.read() 读取整个文件2.readline() 每次读取一行文件3. readlines() 读取文件的所有行2.文件的写入1.以"x"方式打开文件2.以"a"方式打开文件3.以"w"方式打开文件3.文件的删除4.Excel表数据的读取1.直接读取2.通过p…

SQL Server2019配置always on高可用图文步骤

准备工作 首先需要准备好Windows Server上的故障转移群集&#xff0c;步骤可以参考上一篇。 https://blog.csdn.net/u012869793/article/details/127560270?spm1001.2014.3001.5501 然后服务器上安装好SqlServer&#xff0c;我这里安装的是2019。 正文 勾选启用Always ON可…

牛客竞赛每日俩题 - Day7

目录 经典01背包问题 二叉树遍历与构造&#xff08;考研重点&#xff09; 经典01背包问题 求正数数组的最小不可组成和_百度笔试题_牛客网 参考大佬题解&#xff1a; 动态规划&#xff1a;01背包问题(无物品价值)&#xff0c;思想相同&#xff0c;题目最终要求有些变化 min为…

【机器人定位引导中的机器视觉技术】

文章目录手眼标定原理手眼标定流程定位引导1、单相机抓取定位引导2、单相机纠偏定位引导3、上下相机对位引导随着工业生产中对自动化的要求越来越高&#xff0c;视觉技术已被广泛引入工业机器人行业&#xff0c;具备视觉的工业机器人能更快、更准、更灵活地完成定位抓取、对位组…

Linux系统 (三)- 权限介绍

~~~~前言命令行解释器 -- Command Line Interpreter ShellLinux操作系统命令行解释器对命令行解释器的初步认识命令行解释器的意义shell分类命令行解释器 CLI Shell图形界面 GUI ShellLinux权限Linux中用户分类su基本语法sudo基本语法配置操作权限管理权限是什么文件分类文件属…

【一起学数据结构与算法】计数排序、基数排序、桶排序(含菜鸟教程代码)

目录前言一、计数排序1.1 排序思想1.2 代码1.3 菜鸟教程官方代码(搬运)二、基数排序2.1 排序思想2.2 代码2.3 菜鸟教程官方代码(搬运)三、桶排序3.1 排序思想3.2 代码3.3 菜鸟教程官方代码(搬运)前言 之前我们学过了几种常见的排序&#xff0c;都是基于比较的排序&#xff0c;…

ES6中扩展对象的功能性

对象是JavaScript编程的核心&#xff0c;ECMAScript6为对象提供了许多简单易用且更加灵活的新特性。 ECMAScript 6在对象字面量的基础上做出了以下几个变更&#xff1a; 简化属性定义语法&#xff0c;使将当前作用域中的同名变量赋值给对象的语法更加简洁 function createPe…

【MySQL】MySQL基本操作详解

系列文章目录 第1篇&#xff1a;【MySQL】MySQL介绍及安装 第2篇&#xff1a;【MySQL】MySQL基本操作详解 文章目录 ✍1&#xff0c;数据库操作     &#x1f50d;1.1,查看数据库     &#x1f50d;1.2,创建数据库     &#x1f50d;1.3,选择数据库     &…