48天C++笔试强训 001
作者:@小萌新
专栏:@笔试强训
作者简介:大二学生 希望能和大家一起进步!
本篇博客简介:讲解48天笔试强训第一天的题目
笔试强训 day1
- 选择题
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 编程题
- 1
- 2
选择题
1
以下for循环的执行次数是()
for(int x = 0, y = 0; (y = 123) && (x < 4); x++);
A. 是无限循环
B. 循环次数不定
C. 4次
D. 3次
答案: C
知识点:本题考查的知识点主要有两个 1. c语言中for循环的概念 2. 逻辑操作符
关于for循环的考点主要是第一个分号前表示初始条件
第二个分号前表示终止条件
第三个分号前表示增量表达式
具体的知识点可以参考我这篇博客中关于for循环的知识
for循环相关知识
关于逻辑操作符的考点主要是与操作符
与操作符必须全部为真才为真 只要有假就为假
所以说如果我们表达式前面部分为真后面的判断条件就必须要执行
当然如果前面表达式部分为假后面的判断条件就不需要执行了
具体的知识点可以参考我这篇博客中关于操作符的讲解
c语言操作符详解
解析:本题中初始条件为 x=0 y=0 终止条件为 (y =123)&& (x < 4)为假 增量表达式为x++
首先我们的(y = 123)是一个赋值语句 最后我们其实判断的是y是否为真 y被赋值123之后是非0 所以为真 继续判断&&后面的条件判断语句
x = 0 1 2 3 时为真 x = 4时为假 所以说最终for循环的执行次数为4次
2
以下程序的运行结果是()
#include <stdio.h>
int main(void)
{
printf("%s , %5.3s\n", "computer", "computer");
return 0;
}
A. computer , puter
B. computer , com
C. computer , computer
D. computer , compu.ter
答案:B
知识点:本题考查的知识点主要是printf函数相关知识
具体内容可以参考我的这篇博客
printf输出格式
解析:本题中输出字符串格式有一个 %5.3s\n
其中5表示输出的宽度为5
.3s则表示输出字符串的前三个字符所以说输出后的结果应该是这样子 两个空格+字符串前三个字符
所以说本题答案选择B (由于markdown格式的自动对齐功能 可能看上去B选项前面没有两个空格 不是答案错了 这一点需要大家注意一下)
3
下列main()函数执行后的结果为()
int func()
{
int i, j, k = 0;
for(i = 0, j = -1;j = 0;i++, j++)
{
k++;
}
return k;
}
int main()
{
cout << (func(21));
return 0;
}
A. -1
B. 0
C. 1
D. 2
答案: B
知识点:本题考查的主要知识点有1.c语言中for循环的概念 2. 函数调用操作符
关于for循环的相关知识大家参考第一题即可 博客链接也在第一题中给出了
关于函数调用操作符的知识大家可以参考我的这篇博客
函数调用操作符
解析:由于它的判断条件是 j = 0
这是一个赋值操作 判断的是j j为0 恒为假
所以说根本不会进行for循环
最终输出的结果是 (0)
这里不管有没有进行bool类型转换最终的结果都是0
4
下面的程序输出的是什么?
#include <stdio.h>
int main()
{
int a=1,b=2,c=3,d=0;
if(a == 1 && b++==2)
if(b!=2||c--!=3)
printf("%d,%d,%d\n" ,a,b,c);
else
printf("%d,%d,%d\n" ,a,b,c);
else
printf("%d,%d,%d\n" ,a,b,c);
return 0;
}
A. 1,2,3
B. 1,3,2
C. 3,2,1
D. 1,3,3
答案: D
知识点: 本题主要考查的知识点有1. 代码的规范性 2. 逻辑操作符
关于代码的规范性 我们写出的else语句会往上找出一个离他最近且没有被匹配的if进行匹配
一些刚刚接触代码的同学可能会不注重代码的规范性 从而写出像题目这种可读性很差的代码
对于题目代码的正确规范书写如下
#include <stdio.h>
int main()
{
int a = 1 ,b = 2, c = 3, d = 0;
if (a == 1 && b++==2)
{
if (b != 2 || c--!=3)
{
printf("%d,%d,%d\n" , a ,b , c);
}
else
{
printf("%d,%d,%d\n" , a ,b , c)
}
}
else
{
printf("%d,%d,%d\n" , a ,b ,c);
}
}
关于逻辑操作符 我们在第一题中讲解了与操作符 这里出现了一个新的或操作符
它的意思是只要有真就为真
如果前面的逻辑判断有假的就一直往后判断下去
如果前面的逻辑判断有真的就停止判断
解析:首先 a b c的值分别为 1 2 3
由于b++是后置++ 所以说b++ == 2 为真
经过第一个if判断之后 a b c的值变为 1 3 3
在进入if判断里面后我们继续执行语句 b != 2为真 所以说后面的语句不用执行了
输出结果为 1 3 3
5
若有定义语句: int a=10 ; double b=3.14 ; 则表达式 ‘A’+a+b 值的类型是()
A. char
B. int
C. double
D. float
答案:C
知识点:本题考查的知识点主要是整型提升
关于整型提升大家可以参考我的这篇博客
整型提升
解析:一般来说整型提升会提升至占用空间更多那种数据类型 而本题中double占用的空间最多
6
p[1][2]的值是()
int p[][4] = {{1}, {3, 2}, {4, 5, 6}, {0}};
A. 1
B. 0
C. 6
D. 2
答案:B
知识点:本题的知识点主要是二维数组的初始化
具体内容可以参考我的这篇博客
二维数组的初始化
解析:
二维数组存储时候行可以省略 列不可以省略
其中每个大括号表示的是每行的数据 如果不足则以0补充
所以说它在内存中的分布应该是这样子的
1 0 0 0
3 2 0 0
4 5 6 0
0 0 0 0
第二行第三个数字是0
7
选择表达式 11|10 的结果(本题数值均为十进制)()
A 11
B 10
C 8
D 2
答案:A
知识点:本题考查的知识点是二进制和位操作符的使用
具体的位操作符相关知识可以参考我的这篇博客
位操作符相关
解析:11 的二进制可以表示为 1 0 1 1
10的二进制可以表示为 1 0 1 0
位操作如下图
所以说我们最终得到的结果是11
8
func(21)的运行结果是
int fun(int a){
a^=(1<<5)-1;
return a;
}
A 10
B 5
C 3
D 8
答案:A
知识点: 本题考查的知识点主要是位置操作
具体的知识可以参考第七题的博客
解析:我们首先计算括号内的内容 1 << n 的意思就是原来的数字向左移动n位
同样的-1操作也可以在二进制中使用 具体使用效果如下图所示
而21的二进制是 0 0 0 1 0 1 0 1
之后我们只需要异或一下就能得出答案
转化为十进制之后 答案很显然为10
9
若有定义语句:int year=1009,*p=&year;以下不能使变量 year 中的值增至 1010 的语句是()
A *p+=1;
B (*p)++;
C ++(*p)
D *p++
答案: D
知识点: 单目运算符的运算顺序和优先级
知识点很简单 单目操作符是从右往左进行计算的
解析: D选项中根据弹幕操作符的运算顺序 先对于p地址++ 然后解引用 并不能造成任何数值上的改变 还有可能造成野指针问题
10
下面关于"指针"的描述不正确的是()
A 当使用free释放掉一个指针内容后,指针变量的值被置为NULL
B 32位系统下任何类型指针的长度都是4个字节
C 指针的数据类型声明的是指针实际指向内容的数据类型
D 野指针是指向未分配或者已经释放的内存地址
答案:A
知识点:主要知识点是关于指针的相关概念
具体知识可以参考我的下面几篇博客
熟悉指针
指针进阶
解析:
A选项明显错误 当我们free释放掉一个指针内容之后 指针的地址仍未改变
所以说我们要手动置空来防止野指针问题
B选项正确 因为指针实际上就是地址 32位系统下的指针有32个bit位 所以大小是4个字节
C选项正确 这是指针的基本概念
D选项正确 这是野指针的基本概念
编程题
1
组队竞赛
下面我们都将会有题目的截图来代替文字描述 如果大家想要查看题目的文字描述的话可以点击题目超链接进入
知识点:优先级队列的使用
具体的知识点可以参考我的这篇博客
优先级队列
我们使用优先级队列可以很轻松的解决topk问题
解析:本题其实并没有涉及什么算法 更多的难点是思维上的
题目要求我们要将每个队伍中的第二水平高的人相加起来最大
所以说数值最大的人是永远不可能被选上的 因为他肯定不是水平第二高的(第一第二水平相同例外)
那么我们要发挥他的最大用处 就可以让他带一个水平第二高的和一个水平最低的人参赛
那么这就是第一个队伍
第二个队伍以此类推
那么我们很简单就能推出第二个队员的最大水平值 就是水平第二高的
第二个队员的第二大水平值就是水平第四高的
… …以此类推
反应到我们的优先级队列上就是先pop一个最大的 接下来的值就是我们想要的
代码解决方案如下
#include <iostream>
using namespace std;
#include <queue>
int main()
{
int k = 0;
cin >> k;
priority_queue<int> pq1;
int m = 0;
while(cin >> m)
{
pq1.push(m);
}
long long sum = 0;
vector<int> v;
while(k--)
{
pq1.pop();
v.push_back(pq1.top());
pq1.pop();
}
for (auto x : v)
{
sum += x;
}
cout << sum;
return 0;
}
2
删除公共字符串
知识点:哈希表的使用
具体的知识点可以参考我的这篇博客
unorder_map/set的使用
其实一般遇到这种删除的题目我们第一时间就应该想到使用哈希表来简化查找(因为哈希表的查找效率是O(1))
解析:这个题目中我们只需要知道key值存不存在就好了 并不需要知道其他信息所以说使用set就好了
之后我们只需要遍历需要删除的字符串 查找该字符是否要删除 如果不要就加入到新字符串中
思路很简单
代码中还有一个需要注意的点 我们如果使用cin接受字符串的话 遇到空格就会终止
所以说这里我们不能使用cin 必须要使用getline函数接受一句话
参考博客如下
getline
代码表示如下
#include <iostream>
#include <unordered_map>
using namespace std;
#include <string>
#include <unordered_set>
int main()
{
string s1;
string tok;
getline(cin,s1); // 因为有空格 所以说必须要用getline
cin >> tok ;
unordered_set<char> set;
for (auto x : tok)
{
set.insert(x);
}
string ans;
for (auto x : s1)
{
if (set.find(x) == set.end())
{
ans += x;
}
}
cout << ans;
return 0;
}