C语言:刷题日志(1)

2024-09-07 21:52
文章标签 语言 日志 刷题

本文主要是介绍C语言:刷题日志(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.阶乘计算升级版

本题要求实现一个打印非负整数阶乘的函数。

其中n是用户传入的参数,其值不超过1000。如果n是非负整数,则该函数必须在一行中打印出n!的值,否则打印“Invalid input”。

首先,知道阶乘是所有小于及等于该数的正整数的积,并且0的阶乘为1。那么我们先来个简单的阶乘计算吧。


#include<stdio.h>
int Fact(int n)
{if (n <= 1)return 1;elsereturn n * Fact(n - 1);
}
int main()
{int n;scanf("%d", &n);int ret = Fact(n);printf("%d", ret);return 0;
}

 这样,我们就用这段代码来计算一下5的阶乘吧。

我们可以发现我们成功计算了5的阶乘,但我感觉数不够大,想要计算一下100的阶乘。

 我们发现得出的结果居然是0,这明显不是100的阶乘,这是为什么呢?其实原因很明显,就是溢出了,int类型的的数据最大能表示2的16次方减1,然而100的阶乘已经比这个数大了,所以我们就无法正确输出结果,现在题目要求不超过1000,但现在100就已经不行了,我们该怎么解决他呢?

让我们来看一下代码吧! 

#include <stdio.h>void Print_Factorial(const int N)
{char a[3000] = { 0 };//设置一个存放结果的数组int l = 1;//对赋值次数的限制a[0] = 1;//将首元素设置为1if (N < 0)//如果是负数{printf("Invalid input\n");return 0;}for (int i = 2; i <= N; i++)//从2开始进行阶乘{int z = 0;for (int k = 0; k < l; k++)//对数组进行赋值{int t = i * a[k] + z;a[k] = t % 10;z = t / 10;}while (z)//得到进位的数,同时改变下一次上个代码的循环次数{a[l++] = z % 10;z /= 10;}}for (int i = l - 1; i >= 0; i--)//打印结果{printf("%d", a[i]);}
}int main()
{int N;scanf("%d", &N);Print_Factorial(N);return 0;
}

讲解 

我们先举个例子123*12=1476 

 

我们看完这个例子之后我们其实可以用这种方法来推理出他的运算方式 


假设n = 5的阶乘 5! = 1 * 2 * 3 * 4 * 5
i = 2 时 k = 0 k < (l = 1) z = 0t = i * a[0] + z = 2 * 1 + 0 = 2     a[0] = t % 10 = 2 % 10 = 2    z = t / 10 = 2 / 10 = 0
i = 3 时 k = 0 k < (l = 1) z = 0t = i * a[0] + z = 3 * 2 + 0 = 6     a[0] = t % 10 = 6 % 10 = 6    z = t / 10 = 6 / 10 = 0
i = 4 时 k = 0 k < (l = 1) z = 0t = i * a[0] + z = 4 * 6 + 0 = 24    a[0] = t % 10 = 24 % 10 = 4   z = t / 10 = 24 / 10 = 2 由于z != 0进入while循环改变逐渐改变arr[0]arr[1].....的值a[l++] = a[1] = z % 10 = 2 % 10 = 2  z = z / 10 = 2 / 10 = 0
i = 5 时 k = 0 k < (l = 2) z = 0t = i * a[0] + z = 5 * 4 + 0 = 20    a[0] = t % 10 = 20 % 10 = 0   z = t / 10 = 20 / 10 = 2t = i * a[1] + z = 5 * 2 + 2 = 12    a[1] = t % 10 = 12 % 10 = 2   z = t / 10 = 12 / 10 = 1 由于z != 0进入while循环改变逐渐改变arr[0]arr[1].....的值a[l++] = a[2] = z % 10 = 1 % 10 = 1  z = z / 10 = 1 / 10 = 0到这时循环已经结束 由于l++在多次循环之后l=3,而我们所求的结果就是我们在循环期间所改变的arr的值

 看这回我们不只成功的打印了5的阶乘,也成功打印了100的阶乘

二. 然后是几点

有时候人们用四位数字表示一个时间,比如 1106 表示 11 点零 6 分。现在,你的程序要根据起始时间和流逝的时间计算出终止时间。

读入两个数字,第一个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时间经过那么多分钟后是几点,结果也表示为四位数字。当小时为个位数时,没有前导的零,例如 5 点 30 分表示为 530;0 点 30 分表示为 030。注意,第二个数字表示的分钟数可能超过 60,也可能是负数。

输入格式:

输入在一行中给出 2 个整数,分别是四位数字表示的起始时间、以及流逝的分钟数,其间以空格分隔。注意:在起始时间中,当小时为个位数时,没有前导的零,即 5 点 30 分表示为 530;0 点 30 分表示为 030。流逝的分钟数可能超过 60,也可能是负数。

输出格式:

输出不多于四位数字表示的终止时间,当小时为个位数时,没有前导的零。题目保证起始时间和终止时间在同一天内。

输入样例:

1120 110

输出样例:

1310

题目讲解: 

对于题目的描述,我们其实可以发现如果我们将给我们的起始时间去除上100,就是起始的小时模上100得到的就是起始的分钟,这时我们只要将起始分钟加上给我们的流逝分钟再加上小时数乘以60,所得到的就是总的分钟数,当然这时我们让总的分钟数除以60就能得到小时数,然而一天为24小时所以我们需要将小时控制在24小时之内,其实要得到它非常的简单,只需要我们将小时数模上24就可以了,当然求完小时后我们还要求剩余的分钟数,这就很简单了将总的分钟数模上60就能得到剩余的分钟数了,注意如果剩余的分钟数为单个数我们需要进行补零。

#include<stdio.h>
int main()
{int n,m,h,min,H;scanf("%d %d",&n,&m);h=n/100;min=n%100;H=h*60+min+m;printf("%d%02d",(H/60)%24,H%60);}

三.求整数段和

给定两个整数A和B,输出从A到B的所有整数以及这些数的和。

输入格式:

输入在一行中给出2个整数A和B,其中−100≤A≤B≤100,其间以空格分隔。

输出格式:

首先顺序输出从A到B的所有整数,每5个数字占一行,每个数字占5个字符宽度,向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X

输入样例:

-3 8

输出样例: 

   -3   -2   -1    0    12    3    4    5    67    8
Sum = 30

题目讲解:

根据题目我们知道我们要先找到a到b之间的数,这我们只需要运用for循环即可,将i的初始值设为a,将循环条件设置为i<=b,并让每次循环i都加1,这样我们就成功找到了a到b之间的数,之后我们再看看的输出格式的限制他要求我们每打印5个数就要换行并且当最后一行不满5个数的时候也要进行换行。这样其实我们就可以设置一个计数器count,让每输入一个数count就加一,当count=5的时候将他进行换行处理,并且重新将count赋值为0,之后将所有的数加在一起放到sum里,但是输出还要求我们,如果最后不满5个数也要进行换行,所以在循环结束后,如果剩余的数不足5个,就说明count最后没有被重新赋值为0,我们只需要在循环外进行对count是否等于0的判断,如果不等于零就进行换行,最后在打印a到b之间数的和。

#include<stdio.h>
int main()
{int a,b;scanf("%d %d",&a,&b);int sum=0,count=0;int i,j;for(i=a;i<=b;i++){count++;printf("%5d",i);if(count%5==0){printf("\n");count=0;}sum+=i;}if(count!=0){printf("\n");}printf("Sum = %d",sum);return 0;
}

 四.爬动的蠕虫

一条蠕虫长1寸,在一口深为N寸的井的底部。已知蠕虫每1分钟可以向上爬U寸,但必须休息1分钟才能接着往上爬。在休息的过程中,蠕虫又下滑了D寸。就这样,上爬和下滑重复进行。请问,蠕虫需要多长时间才能爬出井?

这里要求不足1分钟按1分钟计,并且假定只要在某次上爬过程中蠕虫的头部到达了井的顶部,那么蠕虫就完成任务了。初始时,蠕虫是趴在井底的(即高度为0)。

输入格式:

输入在一行中顺序给出3个正整数N、U、D,其中D<U,N不超过100。

输出格式:

在一行中输出蠕虫爬出井的时间,以分钟为单位。

输入样例:

12 3 1

输出样例:

11

题目讲解 

题目其实很好理解,就是一条蠕虫向上爬,每分钟能爬u寸,每次爬完之后会进行一分钟的休息同时下滑d寸。这其实就很好理解了,我们只需要设置一个变量x,如果x小于井的长度就让他加上一分钟爬的u寸,同时时间变量t也要加一,但是题目告诉我们如果爬完之后的高度并没有出井,蠕虫就要休息一分钟,并且下滑d寸,所以我们要设置一个判断如果x爬完的高度依然小于n井高,就让x-d,时间同时也加1,当然如果没有达到井上,蠕虫还要进行爬行,所以我们要将这一次的爬行放入循环中,直到蠕虫爬出井,结束循环并打印所消耗的时间。

#include<stdio.h>
int main()
{int n,d,u;scanf("%d%d%d",&n,&u,&d);int x=0,t=0;while(x<n){x+=u;t++;if(x<n){x-=d;t++;}}printf("%d",t);return 0;
}

五.龟兔赛跑

乌龟与兔子进行赛跑,跑场是一个矩型跑道,跑道边可以随地进行休息。乌龟每分钟可以前进3米,兔子每分钟前进9米;兔子嫌乌龟跑得慢,觉得肯定能跑赢乌龟,于是,每跑10分钟回头看一下乌龟,若发现自己超过乌龟,就在路边休息,每次休息30分钟,否则继续跑10分钟;而乌龟非常努力,一直跑,不休息。假定乌龟与兔子在同一起点同一时刻开始起跑,请问T分钟后乌龟和兔子谁跑得快?

输入格式:

输入在一行中给出比赛时间T(分钟)。

输出格式:

在一行中输出比赛的结果:乌龟赢输出@_@,兔子赢输出^_^,平局则输出-_-;后跟1空格,再输出胜利者跑完的距离。

输入样例:

242

输出样例:

@_@ 726

题目讲解 :

时间

乌龟

兔子

0

0

0

190

570

630

10

30

90

200

600

630

20

60

90

210

630

630

30

90

90

220

660

630

40

120

90

230

690

720

50

150

180

240

720

720

60

180

180

250

750

720

70

210

180

260

780

720

80

240

180

270

810

810

90

270

270

100

300

360

110

330

360

120

360

360

130

390

360

140

420

450

150

450

450

160

480

450

170

510

450

180

540

540

我们通过这个表格可以发现90min为一个周期0min,90min,180min,270min,每到这些时间乌龟和兔子就会相遇,并且我们发现兔子在一个周期上总是在起始时间到十分钟,时间到40分钟到之后的10分钟,时间到80到之后的10分钟,即每个周期的0-10min,40-50min,80-90min,在这些期间内兔子才会运动,而乌龟时一直在运动,所以,我们给出时间可以直接计算出乌龟所运动的路程,

而,兔子所运动的路程我们只要找到总时间在这些时间分段里总共出现了多少分钟即可,每找到一次路程就加9,当然我们要利用while循环让时间不停的前进,并在循环中设置判断条件,既然时90min一周期,只要然时间去模上90,看时间是否在0-10min,40-50min,80-90min之内,每在一次路程就加9。

#include<stdio.h>
int main()
{int tu=0,gui=0,t=0,T;scanf("%d",&T);gui=T*3;while(t<T){if((t%90>=0&&t%90<10)||(t%90>=40&&t%90<50)||(t%90>=80&&t%90<90)){tu+=9;}t++;}if(gui>tu)printf("@_@ %d",gui);else if(tu>gui)printf("^_^ %d",tu);elseprintf("-_- %d",tu);return 0;
}

这篇关于C语言:刷题日志(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146259

相关文章

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

如何确定 Go 语言中 HTTP 连接池的最佳参数?

确定 Go 语言中 HTTP 连接池的最佳参数可以通过以下几种方式: 一、分析应用场景和需求 并发请求量: 确定应用程序在特定时间段内可能同时发起的 HTTP 请求数量。如果并发请求量很高,需要设置较大的连接池参数以满足需求。例如,对于一个高并发的 Web 服务,可能同时有数百个请求在处理,此时需要较大的连接池大小。可以通过压力测试工具模拟高并发场景,观察系统在不同并发请求下的性能表现,从而

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou