【C语言16天强化训练】从基础入门到进阶:Day 13
🔥个人主页:艾莉丝努力练剑
❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题、洛谷刷题、C/C++基础知识知识强化补充、C/C++干货分享&学习过程记录
🍉学习方向:C/C++方向学习者
⭐️人生格言:为天地立心,为生民立命,为往圣继绝学,为万世开太平
前言:距离我们学完C语言已经过去一段时间了,在学习了初阶的数据结构之后,博主还要更新的内容就是【C语言16天强化训练】,之前博主更新过一个【C语言刷题12天IO强训】的专栏,那个只是从入门到进阶的IO模式真题的训练。【C语言16天强化训练】既有IO型,也有接口型。和前面一样,今天依然是训练五道选择题和两道编程算法题,希望大家能够有所收获!
目录
一、五道选择题
1.1 题目1
1.2 题目2
1.3 题目3
1.4 题目4
1.5 题目5
二、两道算法题
2.1 统计每个月兔子的总数
2.1.1 题目理解
2.1.2 思路
2.2 数列的和
2.2.1 题目理解
2.2.2 思路
结尾
一、五道选择题
1.1 题目1
题干:如果x = 2014 ,下面函数的返回值是( )
int fun(unsigned int x)
{int n = 0;while(x + 1){n++;x = x | (x + 1);} return n;
}
A. 20 B. 21 C. 23 D. 25
解析:正确答案就是C选项。
这个作用是对整型中0的个数进行统计,x=x|(x+1);的作用是每次循环把x的二进制中从右往左数的最后一位0变成1,一直到变成全1的时候x+1就溢出为全0,循环结束。2014的二进制是0000 0000 000 0000 0000 0111 1101 1110,所以结果是23。
1.2 题目2
题干:下列语句定义 x 为指向 int 类型变量 a 的指针,其中哪一个是正确的( )
A. int a , *x = a; B. int a , *x = &a; C. int *x = &a , a; D. int a , x = a;
解析:正确答案就是B选项。
A选项的x是指针,赋值时使用a不合适,C选项在赋值时a变量还没定义,D选项中的x不是指针,B选项是最合适的。
1.3 题目3
题干:下面有关空指针和未初始化指针,说法错误的是( )
A. 对0x0这个地址取值是非法的
B. 空指针可以确保不指向任何对象或函数; 而未初始化指针则可能指向任何地方
C. 空指针与任何对象或函数的指针值都不相等
D. malloc在其内存分配失败时返回的是一个未初始化的指针
解析:正确答案就是D选项。
malloc函数在内存分配失败时返回NULL,其余选项都正确。
1.4 题目4
题干:若有定义 int a[8]; ,则以下表达式中不能代表数组元素 a[1] 的地址的是( )
A. &a[0]+1 B. &a[1] C. &a[0]++ D. a+1
解析:正确答案就是D选项。
D选项中a计算时是首元素地址,再加1,就是a[1]的地址,AB明显对,C选项a[0]先和++结合,形成一个表达式,不能对表达式取地址,会报错。
1.5 题目5
题干:以下选项中,对基本类型相同的两个指针变量不能进行运算的运算符是( )
A. + B. - C. = D. ==
解析:正确答案就是A选项。
A选项错误,因为两个地址相加无意义也可能越界,所以规定不允许指针相加;
B选项,可以求出两个数据元素储存位置之间的相隔同数据类型的元素个数;
C选项,赋值,没问题;
D选项,判断两指针是否相同。
选择题答案如下:
1.1 C
1.2 B
1.3 D
1.4 D
1.5 A
校对一下,大家都做对了吗?
二、两道算法题
2.1 统计每个月兔子的总数
牛客网链接:HJ37 统计每个月兔子的总数
题目描述:
2.1.1 题目理解
这道题的关键在于寻找数字之间的规律,如果细心的友友会发现这其实是一个斐波那契数列。规律:第 n 个月的兔子数量实际上就是第 n - 1 个斐波那契数。
题意理解——计算斐波那契数列的第n项(从第1项开始:1,1,2,3,5,...),因为兔子生长规律与斐波那契数列相同。如下图所示,博主这里画了一个简单的示意图——
这道题是IO型的,下面是C语言的模版(如果是IO型就可以不用管它们了)——
2.1.2 思路
1、兔子从出生后第三个月开始每月生一只,且不死。
2、设第n个月兔子总数为 f(n),则:
(1)第 1 个月:f(1)=1;
(2)第 2 个月:f(2)=1;
(3)第 n 个月(n ≥ 3):f(n) = f(n - 1)+f(n - 2)(因为新生的兔子数等于两个月前的兔子总数)。
3、直接使用迭代法(循环)计算斐波那契数列即可。
代码演示:
//C语言实现
#include <stdio.h>int main()
{int n;scanf("%d", &n);if (n <= 2){printf("1\n");return 0;}int a = 1, b = 1, c;for (int i = 3; i <= n; i++){c = a + b;a = b;b = c;}printf("%d\n", b);return 0;
}
时间复杂度:O(n),需要迭代n次;
空间复杂度:O(1),仅需几个变量。
同样的,我们知道这里是一个斐波那契数列之后,代码也可以这样实现——
代码演示:
//C语言实现
#include <stdio.h>
int main()
{int n;while (~scanf("%d", &n)) {int num1 = 1, num2 = 1, ret = 0;for (int i = 2; i < n; i++) {ret = num1 + num2;num1 = num2;num2 = ret;}printf("%d\n", ret);} return 0;
}
时间复杂度:O(n),需要迭代n次;
空间复杂度:O(1),仅需几个变量。
我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样——
代码演示:
//C++实现
#include <iostream>
using namespace std;int main()
{int n;cin >> n;if (n <= 2){cout << 1 << endl;return 0;}int a = 1, b = 1, c;for (int i = 3; i <= n; i++){c = a + b;a = b;b = c;}cout << b << endl;return 0;
}
时间复杂度:O(n),空间复杂度:O(1)。
我们目前要写出来C++的写法是非常考验前面C++的学习情况好不好的,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!
2.2 数列的和
牛客网链接:REAL246 数列的和
题目描述:
2.2.1 题目理解
给定n和m,计算数列:n, sqrt(n), sqrt(sqrt(n)), ...(共m项)的和,保留两位小数。
2.2.2 思路
(1)第一项为n,之后每一项是前一项的平方根;
(2)循环m次,每次将当前项加到总和,并更新当前项为它的平方根;
(3)注意精度:使用double类型,输出保留两位小数。
这道题是IO型的,下面是C语言的模版(如果是IO型就可以不用管它们了)——
代码演示:
#include <stdio.h>
#include <math.h>int main()
{int n, m;while (scanf("%d %d", &n, &m) != EOF) {double sum = 0;double current = n;for (int i = 0; i < m; i++) {sum += current;current = sqrt(current);}printf("%.2f\n", sum);}return 0;
}
时间复杂度:O(m),每次循环计算一次平方根(通常为常数时间操作);
空间复杂度:O(1),仅需几个变量。
既然明确了我们调用C语言math库,就可以这样——
求取一个数字的平方根可以使用数学库中的double sqrt(double num) 函数完成,接下来只需要从数字自身开始进行求和并在求和后将 n 自身计算成为自身的平方根即可。
代码演示:
#include <stdio.h>
#include <math.h>int main()
{double m, n;while (~scanf("%lf %lf", &n, &m)) {double sum = 0;while (m-- > 0) {sum += n;//从自身开始以及每次的平方根进行求和n = sqrt(n);//n成为当前自身的平方根}printf("%.2lf\n", sum);} return 0;
}
时间复杂度:O(n);
空间复杂度:O(1)。
我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样——
代码演示:
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;int main()
{int n, m;while (cin >> n >> m) {double sum = 0;double current = n;for (int i = 0; i < m; i++) {sum += current;current = sqrt(current);}cout << fixed << setprecision(2) << sum << endl;}return 0;
}
时间复杂度:O(n),空间复杂度:O(1)。
我们目前要写出来C++的写法是非常考验前面C++的学习情况好不好的,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!
结尾
本文内容到这里就全部结束了,希望大家练习一下这几道题目,这些基础题最好完全掌握!
往期回顾:
【C语言16天强化训练】从基础入门到进阶:Day 12
【C语言16天强化训练】从基础入门到进阶:Day 11
【C语言16天强化训练】从基础入门到进阶:Day 10
【C语言16天强化训练】从基础入门到进阶:Day 9
【C语言16天强化训练】从基础入门到进阶:Day 8
【C语言16天强化训练】从基础入门到进阶:Day 7
【C语言16天强化训练】从基础入门到进阶:Day 6
【C语言16天强化训练】从基础入门到进阶:Day 5
【C语言16天强化训练】从基础入门到进阶:Day 4
【C语言16天强化训练】从基础入门到进阶:Day 3
【C语言16天强化训练】从基础入门到进阶:Day 2
【C语言16天强化训练】从基础入门到进阶:Day 1
结语:感谢大家的阅读,记得给博主“一键四连”,感谢友友们的支持和鼓励!