当前位置: 首页 > news >正文

【C语言16天强化训练】从基础入门到进阶:Day 11


🔥个人主页:艾莉丝努力练剑

❄专栏传送门:《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  最大连续 1 的个数

2.1.1 题目理解

2.1.2 思路

2.2  完全数计算

2.2.1 题目理解

2.2.2 思路

2.2.3  更通用的实现(如果需要验证其他数字)

2.2.4  两种方法的比较:

结尾


一、五道选择题

1.1  题目1

题干:声明以下变量,则表达式: ch / i + (f * d – i) 的结果类型为( )

char ch;
int i;
float f;
double d;

A. char     B. int     C. float     D. double

解析:正确答案就是D。

A选项:ch / i:char 和 int 运算,char 提升为 int,结果为 int。

B选项:f * d:float 和 double 运算,float 提升为 double,结果为 double。

C选项:(f * d – i):double 和 int 运算,int 提升为 double,结果为 double。

D选项:ch / i + (f * d – i) :int 和 double 运算,int 提升为 double,最终结果为 double。

1.2  题目2

题干:关于代码的说法正确的是( )

#include <stdio.h>
int main()
{int x = -1;unsigned int y = 2;if (x > y){printf("x is greater");} else{printf("y is greater");} return 0;
}

A. x is greater     B. y is greater     C. 依赖实现     D. 随机

解析:正确答案就是A。

(1)x是负数(-1),y是无符号整数(2);

(2)当有符号与无符号比较时,有符号数会被转换为无符号数(即 -1 转换为非常大的正数,因为补码表示)。

因此 x > y 为真(-1 转换为无符号是 0xFFFFFFFF,即 4294967295 > 2)。

1.3  题目3

题干:已知有如下各变量的类型说明,则以下不符合C语言语法的表达式是( )

int k, a, b;
unsigned int w = 5;
double x = 1.42;

A. x%3      B. w += -20      C. k = (a = 200 , b = 300)      D. a += a -= a = 9

解析:正确答案就是A。

A. x % 3:取模运算 % 只能用于整数类型,double 不能取模(编译错误)。

B. w += -20:合法(相当于 w += (-20))。

C. k = (a = 200 , b = 300) :逗号表达式,合法(k 被赋值为 300)。

D. a += a -= a = 9:虽然多次赋值,但语法允许(从右到左:a = 9,然后 a -= a 是0,最后a += a得到0),因为赋值运算符是右结合的这里就相当于a += (a -= (a = 9))。

1.4  题目4

题干:下面函数的输出结果是( )

void func()
{int k = 1^(1 << 31 >> 31);printf("%d\n", k);
}

A. 0     B. -1     C. -2     D. 1

解析:正确答案就是C。

(1)1 << 31:将1左移31位(假设32位int),得到 0x80000000(即 -2147483648,最高位为1表示负数)。

(2)1 << 31 >> 31:算术右移31位(符号位扩展),所有位都变为与符号位相同(即全1),得到 0xFFFFFFFF(即 -1)。

(3)1 ^ ( - 1 ):异或运算(1 和 -1 的二进制每一位都相反),结果为 0xFFFFFFFE(即 -2)。

1.5  题目5

题干:如下代码的输出结果是( )

#include <stdio.h>
int main()
{int i = 1;sizeof(i++);printf("%d\n", i);return 0;
}

A. 1     B. 4     C. 2     D. 8

解析:正确答案就是A。

(1)sizeof 是编译时运算符,不会对操作数求值(i++不会执行)。

(2)因此 i 的值保持不变,输出1。

选择题答案如下:

1.1  D

1.2  A

1.3  A

1.4  C

1.5  A

校对一下,大家都做对了吗?


二、两道算法题

2.1  最大连续 1 的个数

力扣链接:485. 最大连续 1 的个数

力扣题解链接:线性扫描解决【最大连续1】问题

题目描述:

2.1.1 题目理解

1、二进制数组特性数组元素只能是0或1,这个限制条件实际上简化了问题;

2、连续性要求我们需要的是连续的1,中间不能有0间隔;

3、最大值寻找不是统计所有1的个数,而是找出最长的连续1序列。

这道题是接口型的,下面是C语言的模版(如果是IO型就可以不用管它们了)——

2.1.2 思路

1、maxCount: 记录历史最大连续1的个数;

2、currentCount: 记录当前连续1的个数;

3、遍历数组,遇到1就增加计数,遇到0就重置计数;

4、每次遇到1时检查是否需要更新最大值。

代码演示:

//C语言实现——线性扫描方法
int findMaxConsecutiveOnes(int* nums, int numsSize) {int maxCount = 0;int currentCount = 0;for (int i = 0; i < numsSize; i++) {if (nums[i] == 1){currentCount++;maxCount = currentCount > maxCount ? currentCount : maxCount;}else {currentCount = 0;}}return maxCount;
}

时间复杂度O(n)

空间复杂度O(1)

我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样——

代码演示:

class Solution {
public:int findMaxConsecutiveOnes(vector<int>& nums) {int maxCount = 0;int currentCount = 0;for (int num : nums) {if (num == 1) {currentCount++;maxCount = max(maxCount, currentCount);}else {currentCount = 0;}}return maxCount;}
};

时间复杂度:O(n),空间复杂度:O(1)

我们目前要写出来C++的写法是非常考验前面C++的学习情况好不好的,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!

2.2  完全数计算

牛客网链接:HJ56 完全数计算

题目描述:

2.2.1 题目理解

我们需要计算1到n之间完全数的个数。已知完全数的定义是:它所有的真因子(除了自身以外的约数)之和等于它本身。

2.2.2 思路

1、问题分析:我们需要找出1到n之间的所有完全数。已知的完全数很少,在n最大为500,000的情况下,可以预先知道可能的完全数。

2、关键点:完全数非常稀少,在给定的范围内(n ≤ 500,000)只有几个完全数(6, 28, 496, 8128等)。但8128大于500,000?实际上500,000 > 8128,所以范围内有4个?但题目示例输入1000输出3(6,28,496),因为8128大于1000。但n最大500,000,8128 < 500,000,所以实际上有4个?但496 < 1000, 8128 > 1000?注意n最大500,000,所以8128(小于500,000)应该包括?但题目示例输入1000输出3,说明1000以内有3个(6,28,496),而500,000以内还有8128。

3、优化思路:由于完全数很少,可以直接检查已知的完全数是否在1到n之间。已知的完全数有6, 28, 496, 8128。下一个完全数是33550336,但远大于500,000,所以无需考虑。

4、算法选择:因此,只需要判断n是否大于等于6、28、496、8128,然后计数即可。

这道题是IO型的,下面是C语言的模版(如果是IO型就可以不用管它们了)——

代码演示:

//C语言实现
#include <stdio.h>int main()
{int n;scanf("%d", &n);int count = 0;if (n >= 6) count++;if (n >= 28) count++;if (n >= 496) count++;if (n >= 8128) count++;printf("%d\n", count);return 0;
}

时间复杂度O(1)

空间复杂度O(1)

1、输入处理:读取整数n。

2、完全数检查:检查n是否大于等于已知的完全数(6, 28, 496, 8128)。每满足一个条件,计数增加。

3、输出结果:打印完全数的个数。

这种方法利用了完全数的稀少性,直接进行条件判断,简单高效。

我们学习了C++之后也可以尝试用C++来实现一下,看看自己前段时间C++学得怎么样——

代码演示:

//C++实现
#include <iostream>
using namespace std;int main()
{int n;cin >> n;int count = 0;if (n >= 6)count++;if (n >= 28)count++;if (n >= 496)count++;if (n >= 8128)count++;cout << count << endl;return 0;
}

时间复杂度:O(1),空间复杂度:O(1)

1、输入处理:使用cin读取整数n。

2、完全数检查通过一系列条件判断来统计完全数的个数。

(1)如果n ≥ 6,计数+1(包含完全数6);

(2)如果n ≥ 28,计数+1(包含完全数28);

(3)如果n ≥ 496,计数+1(包含完全数496);

(4)如果n ≥ 8128,计数+1(包含完全数8128)。

3、输出结果:使用cout输出完全数的个数。

2.2.3  更通用的实现(如果需要验证其他数字)

如果题目要求验证其他数字是否为完全数,可以使用以下更通用的方法:

//C++实现——更通用的实现(如果需要验证其他数字)
#include <iostream>
#include <cmath>
using namespace std;bool isPerfectNumber(int num) 
{if (num <= 1) return false;int sum = 1; // 1是所有数的真因子int sqrt_num = sqrt(num);for (int i = 2; i <= sqrt_num; i++) {if (num % i == 0) {sum += i;if (i != num / i) {sum += num / i;}}}return sum == num;
}int main() 
{int n;cin >> n;int count = 0;// 直接检查已知的完全数(更高效)if (n >= 6) count++;if (n >= 28) count++;if (n >= 496) count++;if (n >= 8128) count++;cout << count << endl;return 0;// 如果需要验证所有数字(效率较低,但更通用)/*for (int i = 2; i <= n; i++) {if (isPerfectNumber(i)) {count++;}}cout << count << endl;return 0;*/
}

时间复杂度:O(1),空间复杂度:O(1)

2.2.4  两种方法的比较

1、直接判断法:利用已知完全数稀少的特性,直接进行条件判断,时间复杂度O(1),是最优解。

2、通用验证法

可以验证任意数字是否为完全数,但时间复杂度较高,对于n=500,000的情况可能会超时。

对于本题,推荐使用第一种直接判断法,因为它既简单又高效。

我们目前要写出来C++的写法是非常考验前面C++的学习情况好不好的,大家可以尝试去写一写,优先掌握C语言的写法,博主还没有介绍C++的算法题,之后会涉及的,敬请期待!


结尾

本文内容到这里就全部结束了,希望大家练习一下这几道题目,这些基础题最好完全掌握!

往期回顾:

【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

结语:感谢大家的阅读,记得给博主“一键四连”,感谢友友们的支持和鼓励!

http://www.dtcms.com/a/350483.html

相关文章:

  • 朴素贝叶斯算法总结
  • 互联网大厂Java面试实录:Spring Boot与微服务架构解析
  • cmd命令行删除文件夹
  • rk3566编译squashfs报错解决
  • QT5封装的日志记录函数
  • 算法练习-遍历对角线
  • 开源夜莺里如何引用标签和注解变量
  • VTK开发笔记(四):示例Cone,创建圆锥体,在Qt窗口中详解复现对应的Demo
  • 使用Cloudflare的AI Gateway代理Google AI Studio
  • 论文阅读:Code as Policies: Language Model Programs for Embodied Control
  • Redis的单线程和多线程
  • Linux_用 `ps` 按进程名过滤线程,以及用 `pkill` 按进程名安全杀进程
  • 记一次RocketMQ消息堆积
  • (二十二)深入了解AVFoundation-编辑:视频变速功能-实战在Demo中实现视频变速
  • 数字人视频创作革命!开源免费无时限InfiniteTalk ,数字人图片 + 音频一键生成无限长视频
  • ADC-工业信号采集卡-K004规格书
  • 智能电视MaxHub恢复系统
  • 【第十章】Python 文件操作深度解析:从底层逻辑到多场景实战​
  • Flink 滑动窗口实战:从 KeyedProcessFunction 到 AggregateFunction WindowFunction 的完整旅程
  • vi/vim 查找字符串
  • h5和微信小程序查看pdf文件
  • 实验1 第一个微信小程序
  • Linux学习-TCP网络协议(补充)
  • 贝叶斯方法和朴素贝叶斯算法
  • tcpdump学习
  • 20250825的学习笔记
  • 2025年09月计算机二级Java选择题每日一练——第七期
  • 配置单区域 OSPF
  • 集群与集群概念
  • 自动修改excel 自动统计文件名称插入 excel辅助工具