视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
NOIP2018普及组初赛题详细解析
2025-09-29 17:14:07 责编:小OO
文档
NOIP2018初赛普及组C++题目+解析

NOIP2018初赛普及组C++题目+解析 

二十四届全国青少年信息学奥林匹克联赛初赛—— 普及组

一、单项选择题(共15 题,每题2 分,共计30 分;每题有且仅有一个正确选项) 

1. 以下哪一种设备属于输出设备:( ) 

A. 扫描仪 B. 键盘 C. 鼠标 D. 打印机 

答案:D

解析:扫描仪是输出设备显而易见

2. 下列四个不同进制的数中,与其它三项数值上不相等的是( )。 

A. (269)16 

B. (617)10 

C. (1151)8 

D. (1001101011)2 

答案: D

解析:都转成二进制,然后前3个都是1001101001,跟D不同

3. 1MB 等于( )。 

A. 1000 字节 B. 1024 字节 

C. 1000 X 1000 字节 D. 1024 X 1024 字节 

答案:D

解析:1 M B = 1024 K B = 1024 ∗ 1024 B 1MB=1024KB=1024*1024B1MB=1024KB=1024∗1024B

4. 广域网的英文缩写是( )。 

A. LAN 

B. WAN 

C. MAN 

D. LNA 

答案:B   A是局域网  C是城域网 

5. 中国计算机学会于( )年创办全国青少年计算机程序设计竞赛。 

A. 1983 

B. 1984 

C. 1985 

D. 1986 

答案:B

6. 如果开始时计算机处于小写输入状态,现在有一只小老鼠反复按照CapsLock、字母键A、字母键S、字母键D、字母键F 的顺序循环按键,即CapsLock、A、S、D、F、CapsLock、A、S、D、F、……,屏幕上输出的第81 个字符是字母( )。 

A. A 

B. S  

C. D  

D. a 

答案:A

解析:取模 

7. 根节点深度为0,一棵深度为h 的满k(k>1)叉树,即除最后一层无任何子节点外,每一层上的所有结点都有k 个子结点的树,共有( )个结点。

A. (kh+1 - 1) / (k - 1) 

B. kh-1 

C. kh 

D. (kh-1) / (k - 1) 

答案:A

解析:

1)假设h=2,k=2,画出完美二叉树,共7个节点。

2)对4个答案代入运算,结果为A

8. 以下排序算法中,不需要进行关键字比较操作的算法是(A)。

A.基数排序

B.冒泡排序

C.堆排序

D.直接插入排序

答案:A

解析: 基数排序是桶排序的扩展,将要排序的元素分配至某些“桶”中,达到排序的作用,不需要关键字比较

9. 给定一个含N 个不相同数字的数组,在最坏情况下,找出其中最大或最小的数,至少需要N - 1 次比较操作。则最坏情况下,在该数组中同时找最大与最小的数至少需要( )次比较操作。(⌈ ⌉表示向上取整,⌊ ⌋表示向下取整) 

A. ⌈3N / 2⌉ - 2 

B. ⌊3N / 2⌋ - 2 

C. 2N - 2 

D. 2N - 4 

答案:A

解析:前两个数比较,大的为最大值, 小的为最小值, 用掉一次比较 后面2 ∗ ( n − 1 ) 2*(n-1)2∗(n−1)个数, 每两个比较, 大的同最大值比较, 小的同最小值比较, 3 ∗ ( n − 1 ) 3*(n-1)3∗(n−1)次比较, 共3 ∗ ( n − 1 ) + 1 = 3 n − 2 3*(n - 1)+1=3n-23∗(n−1)+1=3n−2次比较。

那n个数就是⌈ ( 3 n / 2 ) − 2 ⌉ \\lceil (3n/2)-2 \\rceil⌈(3n/2)−2⌉

10. 下面的故事与( )算法有着异曲同工之妙。从前有座山,山里有座庙,庙里有个老和尚在给小和尚讲故事:“从前有座山,山里有座庙,庙里有个老和尚在给小和尚讲故事:‘从前有座山,山里有座庙,庙里有个老和尚给小和尚讲故事……’” 

A. 枚举 B. 递归 C. 贪心 D. 分治 

答案:B

解析:基础题

11. 由四个没有区别的点构成的简单无向连通图的个数是( )。 

A. 6 

B. 7 

C. 8 

D. 9 

答案:A

解析:

三条边的图有两个(单点的并,长为3的路,星图)

四条边的图有两个(圈,三角形加一条边)

五条边的图有一个(一条边的图的补图)

六条边的图有一个(即4个点的完全图)

12. 设含有10 个元素的集合的全部子集数为S,其中由7 个元素组成的子集数为T,则T / S 的值为( )。 

A. 5 / 32 

B. 15 / 128 

C. 1 / 8 

D. 21 / 128 

答案:B

解析:如果考虑S是10位的二进制,1表示选,0表示不选,然后S = 210 T = C 10 7 T=C107​,T/ S = 15/128

13. 10000 以内,与10000 互质的正整数有( )个。 

A. 2000 

B. 4000 

C. 6000 

D. 8000 

答案:B

解析:10000分解质因子:10000 =2*2*2*2*5*5*5*5,10000以内被2整除的数有5000个,10000以内被5整除的数有2000个,能同时被2和整除的数被重复计算,即被10整除的数,有1000个。被2或5整除的数有:5000 +2000 – 1000 =6000。互质的数有:10000 - 6000 = 4000个

14. 为了统计一个非负整数的二进制形式中1 的个数,代码如下: 

int CountBit(int x) 

int ret = 0; 

while (x) 

ret++; 

___________; 

return ret; 

则空格内要填入的语句是( )。 

A. x >>= 1

B. x &= x - 1 

C. x |= x >> 1

D. x <<= 1

答案:B

解析:x = x&(x-1)其实是二进制从后往前去掉1个1,如果不明白也可以一个数,比如用一个数5=(101)2   A选项模拟,结果为3;B选项模拟,结果为2;C选项模拟,死循环;D选项模拟,死循环

15. 下图中所使用的数据结构是( )。 

A. 哈希表  

B. 栈  

C. 队列  

D. 二叉树

答案:B

解析:最基础的数据结构

二、问题求解(共2 题,每题5 分,共计10 分) 

1. 甲乙丙丁四人在考虑周末要不要外出郊游。 

已知①如果周末下雨,并且乙不去,则甲一定不去;②如果乙去,则丁一定去;③如果丙去,则丁一定不去;④如果丁不去,而且甲不去,则丙一定不去。如果周末丙去了,则甲________(去了/没去)(1 分),乙________(去 

了/没去)(1 分),丁________(去了/没去)(1 分),周末________(下雨/没下雨)(2 分)。 

答案:去了,不去,不去,没下雨

解析:首先丙去了,所以丁不去,然后根据(4)得知甲去了和根据(2)得知乙不去,最后根据(1)得知不下首先丙去了,所以丁不去,然后根据(4)得知甲去了和根据(2)得知乙不去,最后根据(1)得知不下

2. 从1 到2018 这2018 个数中,共有__________个包含数字8 的数。包含数字8 的数是指有某一位是“8”的数, 例如“2018”与“188”。 

答案:544

解析:首先个位数是8的个数是2018 / 10 = 201 2018/10=2012018/10=201加一个2018就是202个,然后十位数是8个位数不是的个数是2018 / 100 ∗ 9 = 180 2018/100*9=1802018/100∗9=180,然后百位数是8,十位个位都不是的是2018 / 1000 ∗ 81 = 162 2018/1000*81=1622018/1000∗81=162。

加起来544

三、阅读程序写结果(共4 题,每题8 分,共计32 分) 

1. #include

char st[100]; 

int main() { 

scanf("%s", st); 

for (int i = 0; st[i]; ++i) { 

if ('A' <= st[i] && st[i] <= 'Z')

st[i] += 1; 

printf("%s\\n", st); 

return 0; 

输入:QuanGuoLianSai 

输出:_________ 

答案:RuanHuoNianTai

解析:大写字母加1

2. #include

int main() { 

int x; 

scanf("%d", &x); 

int res = 0; 

for (int i = 0; i < x; ++i) {

if (i * i % x == 1) { 

++res; 

printf("%d", res); 

return 0; 

输入:15 

输出:_________ 

答案:4

解析:1,4,11,14这4个数

3. 

#include

using namespace std; 

int n, m; 

int findans(int n, int m) { 

if (n == 0) return m; 

if (m == 0) return n % 3; 

return findans(n - 1, m) - findans(n, m - 1) + findans(n - 

1, m - 1); 

int main(){ 

cin >> n >> m;

cout << findans(n, m) << endl;

return 0; 

输入:5 6 

输出:_________ 

答案:8

解析:自己列个表格

n/m

0123456
00123456
11032547
22-141638
30123456
41032547
52-141638
4. #include

int n, d[100]; 

bool v[100]; 

int main() { 

scanf("%d", &n); 

for (int i = 0; i < n; ++i) {

scanf("%d", d + i); 

v[i] = false; 

int cnt = 0; 

for (int i = 0; i < n; ++i) {

if (!v[i]) { 

for (int j = i; !v[j]; j = d[j]) { 

v[j] = true; 

++cnt; 

printf("%d\\n", cnt); 

return 0; 

输入:10 7 1 4 3 2 5 9 8 0 6 

输出:_________ 

答案:6

解析:暴力模拟

四、完善程序(共2 题,每题14 分,共计28 分) 

1. (最大公约数之和)下列程序想要求解整数𝑛的所有约数两两之间最大公约数的和对10007求余后的值,试补全程序。(第一空2 分,其余3 分) 

举例来说,4的所有约数是1,2,4。1和2的最大公约数为1;2和4的最大公约数为2;1和4的最大公约数为1。于是答案为1 + 2 + 1 = 4。 

要求getDivisor 函数的复杂度为𝑂(√𝑛), 函数的复杂度为𝑂(log max(𝑎, 𝑏))。 

#include

using namespace std; 

const int N = 110000, P = 10007; 

int n; 

int a[N], len; 

int ans; 

void getDivisor() { 

len = 0; 

for (int i = 1; (1) <= n; ++i)

if (n % i == 0) { 

a[++len] = i; 

if ( (2) != i) a[++len] = n / i; 

int (int a, int b) { 

if (b == 0) { 

(3) ; 

return (b, (4) ); 

int main() { 

cin >> n;

getDivisor(); 

ans = 0; 

for (int i = 1; i <= len; ++i) {

for (int j = i + 1; j <= len; ++j) {

ans = ( (5) ) % P; 

cout << ans << endl;

return 0; 

(1)i*i

解析:其实就是枚举到sqrt(n)

( 2 ) n/i

解析:防止重复约数

( 3 ) return a

解析:就是个普通的

( 4 ) a%b

解析: 就是个普通的

( 5 ) ans+(a[i],a[j])

解析:根据题目描述枚举约数

2. 对于一个1到𝑛的排列𝑃(即1到𝑛中每一个数在𝑃中出现了恰好一次),令𝑞𝑖为第𝑖个位置之后第一个比𝑃𝑖值更大的位置,如果不存在这样的位置,则𝑞𝑖 = 𝑛 + 

1。举例来说,如果𝑛 = 5且𝑃为1 5 4 2 3,则𝑞为2 6 6 5 6。 

下列程序读入了排列𝑃,使用双向链表求解了答案。试补全程序。(第二空2 分,其余3 分) 

数据范围 1 ≤ 𝑛 ≤ 105。 

#include

using namespace std; 

const int N = 100010; 

int n; 

int L[N], R[N], a[N]; 

int main() { 

cin >> n;

for (int i = 1; i <= n; ++i) {

int x; 

cin >> x;

(1) ; 

for (int i = 1; i <= n; ++i) {

R[i] = (2) ; 

L[i] = i - 1; 

for (int i = 1; i <= n; ++i) {

L[ (3) ] = L[a[i]]; 

R[L[a[i]]] = R[ (4) ]; 

for (int i = 1; i <= n; ++i) {

cout << (5) << " ";

cout << endl;

return 0; 

答案

( 1 )a[x]=i

解析:标记每个值的位置

( 2 ) i+1

解析:右指针

( 3 ) R[a[i]]

解析:删除操作

( 4 ) a[i]

解析:删除操作

( 5 ) R[i]

解析:因为要按原序输出,所以不能写成R [a[i]] 下载本文

显示全文
专题