GESP1级复习

Day 1 基础代码复习

1.1 printf 输出

需要掌握以下使用方法:

  • 保留小数点后若干位输出(重要)
  • 控制输出宽度
  • 掌握 % 的输出语法

保留小数点输出语法如下所示,其中 %.2f 表示保留小数点后 2 位,一行输出两个浮点数。

double x = 3.1745, y = 4.189894;
printf("%.2f %.2f", x, y);  // 输出 3.17 4.19

控制输出宽度语法格式如下,其中 %2d 表示控制输出宽度为 2,不足的补空格,%02d 表示输出宽度为 2,不足的补 0。

int a = 3;
printf("%2d", a);   // 输出 空格3,即 " 3"
printf("%02d", a);  // 输出 03

想要输出 %,使用 %%

printf("%%");  // 输出 %

1.2 编程题 B 题两类输入方式

编程题中常见的输入方式通常可以分为两类:

  1. 给定若干个整数,需要逐个读入处理;
  2. 给定一个区间,需要枚举区间中的每一个整数。

其中,第一类「给定若干个整数」的输入方式更常见,也更需要重点掌握。

1.2.1 给定 N 个整数

常见描述方式如下:

  1. 第一行给定一个整数 N,表示整数个数;
    1. 接下来 N 行,每行一个整数;
    2. 或者接下来 1 行有 N 个整数。
  2. 第一行给定一个整数 T,表示数据组数;
    1. 接下来 T 行,每行给定一个整数。

N 通常表示数据个数,T 通常表示测试数据组数。虽然含义略有不同,但在代码实现上,通常都需要使用循环读入。

判断是否需要循环读入,主要看输入格式和样例输入。如果题目给出 NT,并且后面还有多组数据,通常就需要在循环中读入。

参考以下读入代码,后续程序围绕读入的 x 进行处理。

int n;
cin >> n;

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

    // 后续代码围绕 x 进行处理
}

如果题目中第一行给的是 T,代码形式类似:

int T;
cin >> T;

for (int i = 1; i <= T; i++) {
    int x;
    cin >> x;

    // 后续代码围绕 x 进行处理
}

1.2.2 给定区间范围

给定区间范围的输入,通常分为两种类型:

  • 给定一个整数 N,区间为 [1, N]
  • 给定两个整数 LR,区间为 [L, R]

参考以下代码,后续程序围绕 i 进行处理,i 依次表示区间内的每一个整数。

// 枚举 [1, N]
for (int i = 1; i <= N; i++) {
    // 后续代码围绕 i 进行处理
}

// 枚举 [L, R]
for (int i = L; i <= R; i++) {
    // 后续代码围绕 i 进行处理
}

1.3 整除

关于整除,需要掌握以下代码实现:

  • 判断是否需要向上取整;
  • 判断奇偶性;
  • 判断因数、公因数、公倍数。

判断是否整除的示例代码如下,后续内容都是基于这个写法进行延伸。

int a = 5, b = 10;

if (b % a == 0) {
    cout << "Yes" << endl;
} else {
    cout << "No" << endl;
}

1.3.1 向上取整

如果有余数,说明不能整除,需要对商手动加一。

例如,求 b / a 的向上取整:

int a = 3, b = 10;

if (b % a == 0) {
    cout << b / a << endl;
} else {
    cout << b / a + 1 << endl;
}

上面代码中,10 / 3 = 31,所以需要向上取整,结果为 4

向上取整也支持一步到位的写法:

// 求 x / y 的向上取整
cout << (x + y - 1) / y << endl;

如果发生整除,不会多加一;如果没有发生整除,即存在余数,会自动加一。

参考下面代码:

int a = 3, b = 10;
cout << (b + a - 1) / a << endl;  // 输出 4

int a2 = 5, b2 = 10;
cout << (b2 + a2 - 1) / a2 << endl;  // 输出 2

也可以记成通用公式:

// 求 x 除以 y 的向上取整
int ans = (x + y - 1) / y;

1.3.2 判断奇偶性

如果一个整数能被 2 整除,则它是偶数;否则它是奇数。

int x = 10;

if (x % 2 == 0) {
    cout << "偶数" << endl;
} else {
    cout << "奇数" << endl;
}

1.3.3 判断因数、公因数、公倍数

int n = 12, a = 2, b = 4;

// 判断 a 是否是 n 的因数
if (n % a == 0) {
    // 后续代码
}

// 判断 n 是否是 a 和 b 的公倍数
if (n % a == 0 && n % b == 0) {
    // 后续代码
}

// 判断 a 是否是 b 和 n 的公因数
if (b % a == 0 && n % a == 0) {
    // 后续代码
}

1.4 数学函数

需要掌握以下函数的使用:

  • sqrt(x) 表示开方,即 x\sqrt{x}
  • pow(a, b) 表示幂函数,即 aba^b
  • abs(x) 表示绝对值,即 x|x|

示例代码如下:

#include <bits/stdc++.h>
using namespace std;

int main() {
    double x = sqrt(16);  // 4
    double y = pow(2, 3); // 8
    int z = abs(-5);      // 5

    cout << x << endl;
    cout << y << endl;
    cout << z << endl;

    return 0;
}

需要注意:

  • sqrtpow 的返回值通常是 double
  • 如果题目要求整数结果,可以根据题意再转换为 int
  • 一级考试中,使用 sqrtpow 时,重点是会写、会读、会根据题目公式代入。

1.5 练习清单

题目名称 题目链接 备注
输出 N 个整数 https://gdengeeker.com/p/4216 B 题读入模板
多组输入(2) https://gdengeeker.com/p/3448 应用
公倍数公因数判定 https://gdengeeker.com/p/4112 模板
圆柱体计算 https://gdengeeker.com/p/3497 printf & 数学函数使用
[GESP202412一级] 温度转换 https://gdengeeker.com/p/4274 printf