NOIP2016第二十二届全国青少年信息学奥林匹克联赛初赛普及组C++语言试题选择题讲解
一、单项选择题(共20题,每题1.5分,共计30分;每题有且仅有一个正确选项)
1. 题目
以下不是微软公司出品的软件是()。
A. Powerpoint
B. Word
C. Excel
D. AcrobatReader
答案:D
知识点:常见软件的出品公司。
解析
- A选项:Powerpoint是微软公司开发的演示文稿软件,属于Microsoft Office办公软件套装的一部分,所以A选项错误。
- B选项:Word是微软公司开发的文字处理软件,也是Microsoft Office办公软件套装中的重要组成部分,所以B选项错误。
- C选项:Excel是微软公司开发的电子表格软件,同样是Microsoft Office办公软件套装的成员之一,所以C选项错误。
- D选项:AcrobatReader是Adobe公司开发的用于阅读PDF文件的软件,不是微软公司出品的,所以D选项正确。
2. 题目
如果256种颜色用二进制编码来表示,至少需要()位。
A. 6
B. 7
C. 8
D. 9
答案:C
知识点:二进制编码与颜色数量的关系。
解析
- 因为(2n\geq256)((n)为二进制位数),(28 = 256),所以至少需要8位二进制编码来表示256种颜色。
- A选项:(2^6 = 64),小于256,所以A选项错误。
- B选项:(2^7 = 128),小于256,所以B选项错误。
- C选项:符合计算结果,所以C选项正确。
- D选项:虽然(2^9)大于256,但不是至少需要的位数,所以D选项错误。
3. 题目
以下不属于无线通信技术的是()。
A. 蓝牙
B. WiFi
C. GPRS
D. 以太网
答案:D
知识点:无线通信技术和有线通信技术的区分。
解析
- A选项:蓝牙是一种短距离无线通信技术,常用于设备之间的数据传输,如手机与蓝牙耳机连接等,所以A选项错误。
- B选项:WiFi是一种基于无线局域网的无线通信技术,广泛应用于家庭、办公场所等提供无线网络接入,所以B选项错误。
- C选项:GPRS是通用分组无线服务技术,是一种基于GSM系统的无线分组交换技术,用于移动数据通信,所以C选项错误。
- D选项:以太网是一种有线网络技术,通过网线连接设备进行数据传输,不属于无线通信技术,所以D选项正确。
4. 题目
以下不是CPU生产厂商的是()。
A. Intel
B. AMD
C. Microsoft
D. IBM
答案:C
知识点:CPU生产厂商的了解。
解析
- A选项:Intel是著名的CPU生产厂商,生产了一系列高性能的处理器,所以A选项错误。
- B选项:AMD也是主要的CPU生产厂商,与Intel在市场上有竞争关系,所以B选项错误。
- C选项:Microsoft是一家软件公司,主要开发操作系统(如Windows)和办公软件等,不是CPU生产厂商,所以C选项正确。
- D选项:IBM也曾经生产过CPU,并且在计算机技术发展过程中有重要贡献,所以D选项错误。
5. 题目
以下不是存储设备的是()。
A. 光盘
B. 磁盘
C. 固态硬盘
D. 鼠标
答案:D
知识点:存储设备的概念和常见类型。
解析
- A选项:光盘是一种存储介质,可以用来存储数据,如音乐、视频、软件等,所以A选项错误。
- B选项:磁盘包括软盘和硬盘等,是传统的存储设备,用于存储计算机系统中的数据和程序,所以B选项错误。
- C选项:固态硬盘是一种新型的存储设备,具有读写速度快等优点,用于存储数据,所以C选项错误。
- D选项:鼠标是一种输入设备,用于操作计算机,而不是存储设备,所以D选项正确。
6. 题目
如果开始时计算机处于小写输入状态,现在有一只小老鼠反复按照CapsLock、字母键A、字母键S和字母键D的顺序循环按键,即CapsLock、A、S、D、CapsLock、A、S、D、……,屏幕上输出的第81个字符是字母()。
A. A
B. S
C. D
D. a
答案:A
知识点:循环规律与字符大小写状态的判断。
解析
- 每4次按键为一个循环,81÷4 = 20余1,说明经过20个完整循环后,又按了一次键,这个键是CapsLock,它会切换大小写状态。
- 开始是小写状态,按一次CapsLock后变为大写状态,接下来按字母键A,所以第81个字符是A。
- A选项:符合上述分析,所以A选项正确。
- B选项:不符合循环规律和大小写状态的判断,所以B选项错误。
- C选项:不符合循环规律和大小写状态的判断,所以C选项错误。
- D选项:不符合大小写状态的切换结果,所以D选项错误。
7. 题目
二进制数00101100和00010101的和是()。
A. 00101000
B. 0100001
C. 01000100
D. 00111000
答案:C
知识点:二进制数的加法运算。
解析
- 二进制加法规则是:0 + 0 = 0,0 + 1 = 1,1 + 0 = 1,1 + 1 = 10(向高位进1)。
- 从低位开始相加:00101100 + 00010101 = 01000001(最后一位0 + 1 = 1,倒数第二位0 + 0 = 0,倒数第三位1 + 1 = 10,向高位进1,本位为0,以此类推),所以结果是01000100(前面补0对齐)。
- A选项:计算错误,所以A选项错误。
- B选项:计算错误,所以B选项错误。
- C选项:符合计算结果,所以C选项正确。
- D选项:计算错误,所以D选项错误。
8. 题目
与二进制小数0.1相等的八进制数是()。
A. 0.8
B. 0.4
C. 0.2
D. 0.1
答案:C
知识点:二进制小数与八进制数的转换。
解析
- 二进制转八进制,从小数点开始,每三位二进制数对应一位八进制数。
- 二进制小数0.1,不足三位,在前面补0为0.100,0.100对应的八进制数为0.4(000对应0,100对应4),所以答案是0.4,这里题目可能有误,如果是问二进制小数0.01对应的八进制数,则是0.2(0.010对应0.2)。
- A选项:不符合转换结果,所以A选项错误。
- B选项:按照正确的题目理解应该是0.1对应的八进制数,不是0.4,所以B选项错误(如果题目是0.100对应的八进制数则正确)。
- C选项:如果题目是0.01对应的八进制数,则符合转换结果,所以C选项正确(按照当前题目可能存在的错误理解,答案应该是0.4)。
- D选项:不符合转换结果,所以D选项错误。
9. 题目
以下是32位机器和64位机器的区别的是()。
A. 显示器不同
B. 硬盘大小不同
C. 寻址空间不同
D. 输入法不同
答案:C
知识点:32位机器和64位机器的主要区别。
解析
- A选项:显示器与机器是32位还是64位无关,显示器的选择主要取决于用户需求和显卡等因素,所以A选项错误。
- B选项:硬盘大小可以根据用户的需求进行配置,与机器的32位或64位架构没有直接关系,所以B选项错误。
- C选项:32位机器的寻址空间通常为(2{32})字节,64位机器的寻址空间通常为(2{64})字节,这是它们的一个重要区别,所以C选项正确。
- D选项:输入法的使用与机器的位架构无关,取决于用户安装和设置的输入法软件,所以D选项错误。
10. 题目
以下关于字符串的判定语句中正确的是()
A. 字符串是一种特殊的线性表
B. 串的长度必须大于零
C. 字符串不可以用数组来表示
D. 空格字符组成的串就是空串
答案:A
知识点:字符串的基本概念和性质。
解析
- A选项:字符串可以看作是由字符组成的线性表,它具有线性表的一些特性,如顺序存储、可以进行插入、删除等操作(在一定条件下),所以A选项正确。
- B选项:字符串的长度可以为零,空串就是长度为零的字符串,所以B选项错误。
- C选项:字符串可以用字符数组来表示,这是一种常见的表示方法,所以C选项错误。
- D选项:空格字符组成的串不是空串,空串是不包含任何字符的串,所以D选项错误。
11. 题目
一棵二叉树如右图所示,若采用顺序存储结构,即用一维数组元素存储该二叉树中的结点(根结点的下标为1,若某结点的下标为i,则其左孩子位于下标2i处、右孩子位于下标(2i + 1)处),则图中所有结点的最大下标为()。
A. 6
B. 10
C. 12
D. 15
答案:D
知识点:二叉树的顺序存储结构以及节点下标的计算。
解析
- 按照顺序存储结构的规则,依次计算各节点的下标:
- 根节点下标为1,其左孩子下标为2×1 = 2,右孩子下标为2×1 + 1 = 3;
- 节点2的左孩子下标为2×2 = 4,右孩子下标为2×2 + 1 = 5;
- 节点3的左孩子下标为2×3 = 6,右孩子下标为2×3 + 1 = 7;
- 节点4的左孩子下标为2×4 = 8,右孩子下标为2×4 + 1 = 9;
- 节点5的左孩子下标为2×5 = 10,右孩子下标为2×5 + 1 = 11;
- 节点6的左孩子下标为2×6 = 12,右孩子下标为2×6 + 1 = 13;
- 节点7的左孩子下标为2×7 = 14,右孩子下标为2×7 + 1 = 15。
- 所以图中所有结点的最大下标为15。
- A选项:不符合计算结果,所以A选项错误。
- B选项:不符合计算结果,所以B选项错误。
- C选项:不符合计算结果,所以C选项错误。
- D选项:符合计算结果,所以D选项正确。
12. 题目
若有如下程序段,其中s、a、b、c均己定义为整型变量,且a、c均己赋值(c大于0)。
s = a;
for(b = 1;b <= c;b++)
s = s + 1;
则与上述程序段修改s值的功能等价的赋值语句是()。
答案:s = a + c;
知识点:循环结构与赋值语句的等价性。
解析
- 在给定的程序段中,for循环会执行c次,每次循环s都会加1,所以最终s的值等于a加上c。
- 例如,假设a = 5,c = 3,那么循环执行过程如下:
- 第一次循环:b = 1,s = a + 1 = 6;
- 第二次循环:b = 2,s = 6 + 1 = 7;
- 第三次循环:b = 3,s = 7 + 1 = 8,即s = a + 3。
- 所以与上述程序段修改s值的功能等价的赋值语句是s = a + c。
13. 题目
有以下程序:
#include<iostream>
usingnamespacestd;
intmain()
{
intk = 4,n = 0;
while(n < k)
{
n++;
if(n % 3!= 0)
continue;
k--;
}
cout << k << " " << n << endl;
return0;
}
程序运行后的输出结果是()
A. 2,2
B. 2,3
C. 3,2
D. 3,3
答案:B
知识点:while循环、continue语句的使用以及程序逻辑的分析。
解析
- 程序首先进入while循环,当n < k时循环继续。
- 第一次循环:n = 0,n++后n = 1,因为n % 3!= 0,执行continue语句,直接进入下一次循环。
- 第二次循环:n = 1,n++后n = 2,因为n % 3!= 0,执行continue语句,直接进入下一次循环。
- 第三次循环:n = 2,n++后n = 3,此时n % 3 == 0,不执行continue语句,k–后k = 3。
- 第四次循环:n = 3,n < k不成立,循环结束。
- 所以最终输出结果是2,3。
- A选项:不符合程序运行结果,所以A选项错误。
- B选项:符合程序运行结果,所以B选项正确。
- C选项:不符合程序运行结果,所以C选项错误。
- D选项:不符合程序运行结果,所以D选项错误。
14. 题目
给定含有n个不同的数的数组L = <xi,x2,…>。如果L中存在xi(1 < i < n)使得x1 < x2 <…xi - 1(xi > xi + 1…,则称L是单峰的,并称xi是L的"峰顶"。现在己知L是单峰的,请把a - c三行代码补全到算法中使得算法正确找到L的峰顶。正确的填空顺序是()。
A. c,a,b
B. c,b,a
C. a,b,c
D. b,a,c
答案:A
知识点:单峰数组的查找算法以及代码逻辑的理解。
解析
- 首先应该判断数组中间元素与相邻元素的大小关系,所以先选c。
- 如果中间元素大于相邻元素,则峰顶在左侧,需要向左查找,所以接着选a。
- 如果中间元素小于相邻元素,则峰顶在右侧,需要向右查找,所以最后选b。
- 所以正确的填空顺序是c,a,b。
- A选项:符合分析结果,所以A选项正确。
- B选项:不符合分析结果,所以B选项错误。
- C选项:不符合分析结果,所以C选项错误。
- D选项:不符合分析结果,所以D选项错误。
15. 题目
设简单无向图G有16条边且每个顶点的度数都是2,则图G有()个顶点。
A. 10
B. 12
C. 8
D. 16
答案:D
知识点:无向图的边数与顶点度数的关系。
解析
- 根据无向图的握手定理:所有顶点的度数之和等于边数的2倍。
- 设图G有n个顶点,已知每个顶点的度数都是2,边数为16,则(2n = 16×2),解得n = 16。
- A选项:不符合计算结果,所以A选项错误。
- B选项:不符合计算结果,所以B选项错误。
- C选项:不符合计算结果,所以C选项错误。
- D选项:符合计算结果,所以D选项正确。
16. 题目
有7个一模一样的苹果,放到3个一样的盘子中,一共有()种放法。
A. 7
B. 8
C. 21
D. 37
答案:B
知识点:组合数学中的分配问题。
解析
- 可以通过列举法来分析:
- 7个苹果放一个盘子,其余两个盘子空着,有1种放法;
- 6个苹果放一个盘子,1个苹果放另一个盘子,第三个盘子空着,有3种放法(因为放1个苹果的盘子可以是三个盘子中的任意一个);
- 5个苹果放一个盘子,2个苹果放另一个盘子,第三个盘子空着,有3种放法;
- 4个苹果放一个盘子,3个苹果放另一个盘子,第三个盘子空着,有2种放法;
- 3个苹果放一个盘子,3个苹果放另一个盘子,1个苹果放第三个盘子,有1种放法。
- 总共的放法有:1 + 3 + 3 + 2 + 1 = 8种。
- A选项:不符合列举结果,所以A选项错误。
- B选项:符合计算结果,所以B选项正确。
- C选项:不符合列举结果,所以C选项错误。
- D选项:不符合列举结果,所以D选项错误。
17. 题目
下图表示一个果园灌溉系统,有A、B、C、D四个阀门,每个阀门可以打开或关上,所有管道粗细相同,以下设置阀门的方法中,可以让果树浇上水的是()。
A. B打开,其他都关上
B. AB都打开,CD都关上
C. A打开,其他都关上
D. D打开,其他都关上
答案:A
知识点:对灌溉系统中阀门设置与水流路径的逻辑分析。
解析
- 观察灌溉系统图可知,只有B阀门打开时,水可以通过相应管道到达果树进行灌溉,其他阀门关闭不会影响水通过B阀门到达果树。
- A选项:符合灌溉系统的水流路径要求,所以A选项正确。
- B选项:AB都打开可能会改变水流路径,导致水不一定能顺利到达果树,所以B选项错误。
- C选项:A打开时,根据图中管道连接情况,水无法到达果树,所以C选项错误。
- D选项:D打开时,水无法到达果树,所以D选项错误。
18. 题目
Lucia和她的朋友以及朋友的朋友都在某社交网站上注册了账号。下图是他们之间的关系图,两个人之间有边相连代表这两个人是朋友,没有边相连代表不是朋友。这个社交网站的规则是:如果某人A向他(她)的朋友B分享了某张照片,那么B就可以对该照片进行评论;如果B评论了该照片,那么他(她)的所有朋友都可以看见这个评论以及被评论的照片,但是不能对该照片进行评论(除非A也向他(她)分享了该照片)。现在Lucia已经上传了一张照片,但是她不想让Jacob看见这张照片,那么她可以向以下朋友()分享该照片。
A. Dana, Michael, Eve
B. Dana, Eve, Monica
C. Michael, Eve, Jacob
D. Micheal, Peter, Monica
答案:A
知识点:对社交网站分享规则和关系图的逻辑分析。
解析
- 从关系图中分析,如果Lucia向Dana、Michael、Eve分享照片,由于Jacob与他们之间没有直接或间接的路径(通过朋友关系)使得Jacob能够看到照片分享的路径,所以Jacob无法看到照片。
- A选项:符合要求,所以A选项正确。
- B选项:如果向Monica分享,Monica的朋友可能会使Jacob看到照片,不符合要求,所以B选项错误。
- C选项:包含Jacob,不符合要求,所以C选项错误。
- D选项:如果向Peter分享,Peter的朋友可能会使Jacob看到照片,不符合要求,所以D选项错误。
19. 题目
周末小明和爸爸妈妈三个人一起想动手做三道菜。小明负责洗菜、爸爸负责切菜、妈妈负责炒菜。假设做每道菜的顺序都是:先洗菜10分钟,然后切菜10分钟,最后炒菜10分钟。那么做一道菜需要30分钟。注意:两道不同的菜的相同步骤不可以同时进行。例如第一道菜和第二道的菜不能同时洗,也不能同时切。那么做完三道菜的最短时间需要()分钟。
A. 90
B. 60
C. 50
D. 40
答案:C
知识点:任务安排与时间优化问题。
解析
- 要使时间最短,可以采用并行操作的方式。
- 第一步:小明洗第一道菜10分钟,同时爸爸切第二道菜10分钟,妈妈炒第三道菜10分钟;
- 第二步:小明洗第二道菜10分钟,同时爸爸切第三道菜10分钟,妈妈炒第一道菜10分钟;
- 第三步:小明洗第三道菜10分钟,同时爸爸切第一道菜10分钟,妈妈炒第二道菜10分钟。
- 总共花费的时间为:10×5 = 50分钟。
- A选项:按照顺序做三道菜需要90分钟,但不是最短时间,所以A选项错误。
- B选项:不是最短时间,所以B选项错误。
- C选项:符合时间优化后的结果,所以C选项正确。
- D选项:不符合计算结果,所以D选项错误。
20. 题目
参加NOI比赛,以下不能带入考场的是()。
A. 钢笔
B. 适量的衣服
C. U盘
D. 铅笔
答案:C
知识点:比赛考场规则对物品的要求。
解析
- A选项:钢笔可以带入考场用于书写,所以A选项错误。
- B选项:适量的衣服可以根据实际情况带入考场,以适应考场环境,所以B选项错误。
- C选项:U盘可能存储有与考试相关的资料,为了保证考试的公平性,不允许带入考场,所以C选项正确。
- D选项:铅笔可以带入考场用于答题等,所以D选项错误。
二、问题求解(共2题,每题5分,共计10分;第一题全部答对得5分,没有部分分;第二题第一空2分,第二空3分)
1. 题目
从一个4×4的棋盘(不可旋转)中选取不在同一行也不在同一列上的两个方格,共有多少种方法?
答案:72
知识点:组合数学中的排列组合问题,棋盘方格选取的限制条件运用。
解析
- 第一步,从16个方格中任选一个方格,有16种选法。
- 第二步,由于所选的第二个方格不能在第一个方格的行和列上,那么对于第一个方格所在的行和列,一共去掉了4 + 4 - 1 = 7个方格(行和列交叉处的方格重复计算了一次,所以要减去1),此时剩下16 - 7 = 9个方格可供选择第二个方格。
- 但是这样选取会有重复情况,比如先选第一行第一列的方格,再选第二行第二列的方格,与先选第二行第二列的方格,再选第一行第一列的方格是同一种情况,但在上述计算中被重复计算了。所以总的方法数应该是(16×9÷2 = 72)种。
2. 题目
约定二叉树的根节点高度为1。一棵结点数为2016的二叉树最少有多少个叶子结点;一棵结点数为2016的二叉树最小的高度值是多少?
答案:1(2分);11(3分)
知识点:二叉树的性质,包括叶子结点数量与树的高度和结点总数的关系。
解析
- 第一问:
- 当二叉树为完全二叉树时,叶子结点数量最少。对于完全二叉树,其叶子结点数为(n_0),度为2的结点数为(n_2),则(n_0 = n_2 + 1)。
- 设度为2的结点数为(x),则叶子结点数为(x + 1),总节点数(n = n_0 + n_1 + n_2)((n_1)为度为1的结点数),在完全二叉树中(n_1)最多为1个。
- 因为(n = 2016),当(n_1 = 0)时,(n = 2x + 1),解得(x = 1007.5)(不符合实际情况);当(n_1 = 1)时,(n = 2x + 2),解得(x = 1007),所以叶子结点数(x + 1 = 1008),但是这里要求最少的叶子结点数,我们可以让二叉树退化为一条链(除了叶子结点外每个结点只有一个孩子),此时叶子结点数为1。
- 第二问:
- 同样考虑完全二叉树的情况,完全二叉树的高度(h = \lfloor log_2n \rfloor + 1)((n)为节点总数)。
- 对于(n = 2016),(\lfloor log_22016 \rfloor + 1 = \lfloor 10.97 \rfloor + 1 = 11),所以一棵结点数为2016的二叉树最小的高度值是11。
三、阅读程序写结果(共4题,每题8分,共计32分)
1. 题目
#include<iostream>
usingnamespacestd;
intmain()
{
intmax,min,sum,count = 0;
inttmp;
cin >> tmp;
if(tmp == 0)return0;
max = min = sum = tmp;
while(tmp!= 0)
{
count++;
cin >> tmp;
if(tmp!= 0)
{
sum += tmp;
count++;
if(tmp > max)max = tmp;
if(tmp < min)min = tmp;
}
}
cout << max << "," << min << "," << sum / count << endl;
return0;
}
输入:12345607
答案:6,1,3
知识点:程序对输入数据的处理逻辑,包括寻找最大值、最小值以及计算平均值。
解析
- 程序首先读入一个数,如果是0则结束程序。这里读入1,将1赋值给max、min和sum,count初始化为1。
- 然后继续读入数据,只要不是0就进行处理。读入2、3、4、5、6时,sum依次累加这些数,count也依次增加,同时更新max和min的值。
- 当读入0时,循环结束,但由于后面还有一个7,所以7被忽略。
- 最后计算平均值sum / count,此时sum = 1 + 2 + 3 + 4 + 5 + 6 = 21,count = 6,平均值为21 / 6 = 3(整数除法取整),max = 6,min = 1,所以输出6,1,3。
2. 题目
#include<iostream>
usingnamespacestd;
intmain()
{
inti = 100,x = 0,y = 0;
while(i > 0)
{
i--;
x = i % 8;
if(x == 1)y++;
}
cout << y << endl;
return0;
}
答案:13
知识点:循环结构中对变量的操作以及条件判断。
解析
- 程序从100开始每次减1,直到i > 0不成立。对于每次的i,计算i % 8的值。
- 当i % 8 == 1时,y的值就增加1。
- 从100到1,满足i % 8 == 1的数有:1,9,17,25,33,41,49,57,65,73,81,89,97,共13个,所以y最终的值为13。
3. 题目
#include<iostream>
usingnamespacestd;
intmain()
{
int a[6] = {1,2,3,4,5,6};
int pi = 0;
int pj = 5;
int t;
while(pi < pj)
{
t = a[pi];
a[pi] = a[pj];
a[pj] = t;
pi++;
pj--;
}
for(int i = 0; i < 6; i++)
cout << a[i] << " ";
cout << endl;
return0;
}
答案:6,5,4,3,2,1,
知识点:数组元素的交换操作以及循环结构的运用。
解析
- 程序通过一个循环,使用中间变量t,将数组a的首尾元素依次交换。
- 第一次循环:t = a[0] = 1,a[0] = a[5] = 6,a[5] = t = 1;pi变为1,pj变为4。
- 第二次循环:t = a[1] = 2,a[1] = a[4] = 5,a[4] = t = 2;pi变为2,pj变为3。
- 第三次循环:t = a[2] = 3,a[2] = a[3] = 4,a[3] = t = 3;此时pi = 3,pj = 2,循环结束。
- 最后通过循环输出数组a的元素,得到6,5,4,3,2,1,
4. 题目
#include<iostream>
usingnamespacestd;
intmain()
{
int length1,length2;
string s1 = "haveadream.";
string s2 = "HaveADream.";
length1 = s1.size();
length2 = s2.size();
for(int i = 0; i < length1; i++)
if(s1[i] >= 'a' && s1[i] <= 'z')
s1[i] -= 'a' - 'A';
for(int i = 0; i < length2; i++)
if(s2[i] >= 'a' && s2[i] <= 'z')
s2[i] -= 'a' - 'A';
if(s1 == s2)cout << "=" << endl;
else if(s1 > s2)cout << ">" << endl;
else cout << "<" << endl;
return0;
}
答案:=
知识点:字符串的操作,包括大小写转换以及字符串比较。
解析
- 程序首先获取两个字符串s1和s2的长度。
- 然后通过循环将s1和s2中的小写字母转换为大写字母。
- 对于s1,转换后变为“HAVEADREAM.”;对于s2,本身就是“HaveADream.”,转换后也变为“HAVEADREAM.”。
- 最后比较两个转换后的字符串,由于它们相等,所以输出“=”。
四、完善程序(共2题,每题14分,共计28分)
1. 题目
(读入整数)请完善下面的程序,使得程序能够读入两个int范围内的整数,并将这两个整数分别输出,每行一个。(第一、五空2.5分,其余3分)
输入的整数之间和前后只会出现空格或者回车。输入数据保证合法。
例如:
输入:123 -789
输出:123
-789
#include<iostream>
usingnamespacestd;
{
intnum = 0;//存储读取到的整数
intnegative = 0;//负数标识
intreadint()
{
charc;//存储当前读取到的字符
c = cin.get();
while((c < '0' || c > '9') && c!= '-')
c = (1);
if(c == '-')negative = 1;
else(2);
c = cin.get();
while((3))
(4);
c = cin.get();
}
{
if(negative == 1)(5);
intmain()
{
inta,b;
a = readint();
b = readint();
cout << a << endl << b << endl;
return0;
}
}
答案
(1) cin.get()
(2) num = c - '0’或num = c - 48
(3) >= ‘0’ && <= '9’或 >= 48 && <= 57
(4) num = num * 10 + c或num = num * 10 + c - 48
(5) num = -num或return -num
知识点:字符输入处理,整数的字符形式转换为整型数,包括正负号的处理。
解析
- 第一空:当读入的字符不是数字且不是负号时,需要继续读入下一个字符,所以填cin.get()。
- 第二空:当读入的字符是数字时,需要将字符转换为对应的数字值,即num = c - ‘0’('0’的ASCII码值为48,所以也可以写成num = c - 48)。
- 第三空:在处理数字部分时,需要判断读入的字符是数字,即 >= ‘0’ && <= ‘9’(也可以写成 >= 48 && <= 57,因为’0’到’9’的ASCII码值是48到57)。
- 第四空:将读入的数字字符组成整数,每读入一个数字字符,需要将之前的结果乘以10再加上当前数字的值,即num = num * 10 + c(或者num = num * 10 + c - 48)。
- 第五空:如果是负数,需要将最终得到的数取相反数,即num = -num(或者return -num,这里两种方式都可以,根据程序结构选择合适的方式)。
2. 题目
(郊游活动)有n名同学参加学校组织的郊游活动,已知学校给这n名同学的郊游总经费为A元,与此同时第i位同学自己携带了Mi元。为了方便郊游,活动地点提供
B
(
≥
n
)
B(≥n)
B(≥n) 辆自行车供人租用,租用第j辆自行车的价格为Cj元,每位同学可以使用自己携带的钱或者学校的郊游经费,为了方便账务管理,每位同学只能为自己租用自行车,且不会借钱给他人,他们想知道最多有多少位同学能够租用到自行车。(第四、五空2.5分,其余3分)
本题采用二分法。对于区间[,r],我们取中间点mid并判断租用到自行车的人数能否达到mid。判断的过程是利用贪心算法实现的。
#include<iostream>
usingnamespacestd;
#defineMAXN1000000
intn,B,A,M[MAXN],C[MAXN],l,r,ans, mid;
boolcheck(intnn)
{
int i = (1);
int j = 1;
{
intcount = 0,i,j;
while(i <= n)
{
if(M[i] < C[j])
count += C[j] - M[i];
i++;
j++;
}
}
return(3);
}
voidsort(inta[],int l,int r)
{
int i = 1,j = r,x = a[(l + r)/2],y;
while(i <= j)
{
while(a[i] < x)i++;
while(a[i] > x)j--;
if(i <= j)
{
y = a[i];
a[i] = a[j];
a[j] = y;
i++;j--;
}
}
if(i < r)sort(a,i,r);
if(l < j)sort(a,l,j);
}
intmain()
{
int i;
cin >> n >> B >> A;
for(i = 1;i <= n;i++)
cin >> M[i];
for(i = 1;i <= B;i++)
cin >> C[i];
sort(M,1,n);
sort(C,1,B);
l = 0;
r = n;
while(l <= r)
{
mid = (l + r)/2;
if((4))
{
ans = mid;
l = mid + 1;
}
else
r = (5);
}
cout << ans << endl;
return0;
}
答案
(1) n - nn + 1
(2) M[i] < C[j](或M[i] <= C[j])
(3) count <= A
(4) check(mid)
(5) mid - 1
知识点:二分法的应用,贪心算法在判断租用自行车人数问题中的应用,数组排序算法。
解析
- 第一空:在check函数中,需要从第n - nn + 1个同学开始检查是否能够租用自行车,所以填n - nn + 1。
- 第二空:当同学自己携带的钱M[i]小于租用自行车的价格C[j]时,需要计算差价,所以这里填M[i] < C[j](也可以填M[i] <= C[j])。
- 第三空:判断是否满足经费条件,即计算出的总花费count不能超过总经费A,所以填count <= A。
- 第四空:在二分法的过程中,需要判断中间点mid对应的租用自行车人数是否满足条件,所以调用check(mid)函数。
- 第五空:当中间点mid不满足条件时,需要更新右边界r为mid - 1,继续在左半区间查找。