NOIP 2018 普及组初赛

发布时间 2023-09-05 18:04:19作者: RonChen

T1

以下哪一种设备属于输出设备

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

D

T2

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

  • A. \((269)_{16}\)
  • B. \((617)_{10}\)
  • C. \((1151)_8\)
  • D. \((1001101011)_2\)
答案

D

A. \((269)_{16} = 2 \times 16^2 + 6 \times 16 + 9 = 617\)
C. \((1151)_8 = 8^3 + 8^2 + 5 \times 8 + 1 = 617\)

T3

1MB 等于

  • A. 1000 字节
  • B. 1024 字节
  • C. 1000×1000 字节
  • D. 1024×1024 字节
答案

D

计算机存储信息的基本单位是“字节”即 Byte
常用的单位还有 KB,MB,GB,TB 等
1 Byte = 8 bit
1 KB = 1024 Byte = \(2^{10}\) Byte ~ \(10^3\)
1 MB = 1024 KB = \(2^{20}\) Byte ~ \(10^6\)
1 GB = 1024 MB = \(2^{30}\) Byte ~ \(10^9\)
1 TB = 1024 GB = \(2^{40}\) Byte ~ \(10^{12}\)

T4

广域网的英文缩写是

  • A. LAN
  • B. WAN
  • C. MAN
  • D. LNA
答案

B

广域网(Wide Area Network,缩写为 WAN)又称外网、公网,是连接不同地区局域网或城域网计算机通信的远程网。通常跨接很大的物理范围,所覆盖的范围从几十公里到几千公里,它能连接多个地区、城市和国家,或横跨几个洲并提供远距离通信,形成国际性的远程网络。

局域网(Local Area Network,缩写为 LAN)是一个可连接住宅,学校,实验室,大学校园或办公大楼等有限区域内计算机的网络。

城域网(Metropolitan Area Network,缩写为 MAN)是介于 LAN 和 WAN 之间能传输语音与数据的公用网络。

T5

中国计算机学会于哪一年创办全国青少年计算机程序设计竞赛

  • A. 1983
  • B. 1984
  • C. 1985
  • D. 1986
答案

B

T6

如果开始时计算机处于小写输入状态,现在有一只小老鼠反复按照 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

A、S、D、F、a、s、d、f 循环出现
81/8=10 余 1

T7

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

  • A. \((k^{h+1}-1)/(k-1)\)
  • B. \(k^{h-1}\)
  • C. \(k^h\)
  • D. \((k^{h-1})/(k-1)\)
答案

A

等比数列求和
\(1+k^1+k^2+\cdots+k^{h+1}=(1-k^{h+1})/(1-k)\)

T8

以下排序算法中,不需要进行关键字比较操作的是

  • A. 基数排序
  • B. 冒泡排序
  • C. 堆排序
  • D. 直接插入排序
答案

A

图解排序算法(一)之3种简单排序(选择,冒泡,直接插入)
图解排序算法(二)之希尔排序
图解排序算法(三)之堆排序
图解排序算法(四)之归并排序
图解排序算法(五)之快速排序——三数取中法

T9

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

  • A. \(\lceil 3N/2 \rceil -2\)
  • B. \(\lfloor 3N/2 \rfloor -2\)
  • C. \(2N-2\)
  • D. \(2N-4\)
答案

A

同时找最大最小值的优化算法:

  • 若 N 为奇数,最大值、最小值的初始值都设为第一个元素;若 N 为偶数,将前两个元素比较,最大值初始值设为大的元素,最小值初值设为小的元素。
  • 接下来每次取后面的 2 个元素进行比较,分出大小。大的元素拿来和最大值比较,小的元素和最小值比较。
  • 循环结束时得到最大、最小值。

N 为奇数时,比较次数为 2*(N-1)/2=(3N+1)/2-2
N 为偶数时,比较次数为 1+3*(N-2)/2=3N/2-2

T10

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

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

B

T11

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

  • A. 6
  • B. 7
  • C. 8
  • D. 9
答案

A

简单图:既不含平行边也不含自环的图。
在无向图中,关联一对顶点的无向边如果多于 1 条,则称这些边为平行边,平行边的条数称为重数。在有向图中,关联一对顶点的有向边如果多于 1 条,并且这些边的始点和终点相同(也就是它们的方向相同),称这些边为平行边。含平行边的图称为多重图,既不含平行边也不含自环的图称为简单图。

四个没有区别的点,意味着以下的图形为相同形状。若四个点的度分别为 1,1,2,2,则下图中的图本质相同。
image

根据边数分类讨论:

  • 小于 3 条边,不构成连通图
  • 3 条边:度数 1,1,2,2 和 1,1,1,3
  • 4 条边:度数 2,2,2,2 和 1,2,2,3
  • 5 条边:度数 2,2,3,3
  • 6 条边:度数 3,3,3,3
    image

T12

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

  • A. 5/32
  • B. 15/128
  • C. 1/8
  • D. 21/128
答案

B

子集总数为 \(2^{10}=1024\),10 个元素每个都可以选或不选。
7 个元素集合数 T 为 C(10,7)=10!/(3!7!)=120
T/S=120/1024=15/128

T13

10000 以内,与 10000 互质的正整数有多少个

  • A. 2000
  • B. 4000
  • C. 6000
  • D. 8000
答案

B

公约数只有 1 的两个整数,叫做互质整数。
对 10000 分解质因子:\(10000=2^4 \times 5^5\)
10000 以内被 2 整除的数有 5000 个
10000 以内被 5 整除的数有 2000 个
重复计算的数,即被 10 整除的数,有 1000 个
被 2 或 5 整除的数有:5000+2000-1000=6000
则既不能被 2 也不能被 5 整除的数,即与 10000 互质的数有:10000-6000=4000 个

T14

为了统计一个非负整数的二进制形式中 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

image

T15

下图中所使用的数据结构是
image

  • A. 哈希表
  • B. 栈
  • C. 队列
  • D. 二叉树
答案

B

只有一个出口,要想把底下的东西拿出来,只能把上面的东西先拿走,所以是栈。

T16

甲乙丙丁四人在考虑周末要不要外出郊游。
已知:①如果周末下雨,并且乙不去,则甲一定不去;②如果乙去,则丁一定去;③如果丙去,则丁一定不去;④如果丁不去,而且甲不去,则丙一定不去。如果周末丙去了,则甲(去了/没去),乙(去了/没去),丁(去了/没去),周末(下雨/没下雨)

答案

去了;没去;没去;没下雨

根据③,丙去了,那么丁没去;根据②的逆否命题,丁没去,乙一定没去;根据④的逆否命题(结合德摩根律),丙去了,则丁去了或者甲去了,而丁没去,那么甲一定去了;根据①的逆否命题(结合德摩根律),甲去了,则不下雨或者乙去了,而乙没去,周末一定没下雨

T17

从 1 到 2018 这 2018 个数中,共有多少个包含数字 8 的数(包含 8 的数是指有某一位是“8”的数,例如“2018”与“188”)

答案

544

  • 个位数是 8(其他位随意)的数的个数是 202
  • 十位数是 8(百位随意),个位数不是 8 的数的个数是 2018/100*9=180
  • 百位数是 8,十位个位都不是 8 的数的个数是 2018/1000*81=162

T18

#include <cstdio>
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,输出:

答案

RuanHuoMianTai

T19

#include <cstdio>
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

将 0 到 14 中所有数平方对 15 取模判断是否为 1 即可,当 i=1,4,11,14 时满足条件

T20

#include <iostream>
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

可以转化为递推
image

T21

#include <cstdio>
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

n 个点、n 条边,每个点出度为 1,统计连通块的数量
image
当 n 个点,每个点配 1 条出边时,一个连通块最多 1 个环

T22

(最大公约数之和)下列程序想要求解整数 n 的所有约数两两之间最大公约数的和对 10007 求余后的值,试补全程序。举例来说,4 的所有约数是 1,2,4。1 和 2 的最大公约数为 1;2 和 4 的最大公约数为 2;1 和 4 的最大公约数为 1,于是答案为 1+2+1=4
要求 getDivisor 函数的复杂度为 \(O(\sqrt n)\),gcd 函数的复杂度为 \(O(\log \max(a,b))\)

#include <iostream>
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 gcd(int a, int b) {
    if (b == 0) {
        _____(3)_____;
    }
    return gcd(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
(2)n / i
(3)return a
(4)a % b
(5)ans + gcd(a[i], a[j])

T23

对于一个 1 到 n 的排列 P(即 1 到 n 中每一个数在 P 中出现了恰好一次),令 q[i] 为第 i 个位置之后第一个比 P[i] 值更大的位置,如果不存在这样的位置,则 q[i]=n+1。举例来说,如果 n=5 且 P 为 1 5 4 2 3,则 q 为 2 6 6 5 6
下列程序读入了排列 P,使用双向链表求解了答案,试补全程序,数据范围 \(1 \le n \le 10^5\)

#include <iostream>
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]

  • a[i] 表示大小为 i 的元素所在的位置
  • 第 14-17 行对双向链表进行初始化
  • 第 19-20 行表示删除链表中本元素,本元素右边元素的左指针跨过本元素指向左侧元素,左边元素的右指针指向右侧元素
  • 输出第 i 个数的后继元素即第一个比它大的元素,即 R[i]

算法思想:按照升序将数值 i 所在节点删除掉。当前节点剩下的所有节点中的最小节点,所以它的右侧第一个节点就是它的答案(右侧第一个比当前节点大的节点的下标)