第一题

思路:

利用真人判断的绝对性,反向排除 “不可能是真人” 的位置,这些位置就是最少机器人

  1. 优先假设所有位置是真人,但真人的判断必须正确;
  2. 当 a[i]='1' 时,若 i 位是真人,i+1 位必须是机器人(增加机器人数量),为了 “最少”,我们选择让 i 位是机器人(这样 i+1 位可以是真人,减少机器人);
  3. 最终统计所有 “无法是真人” 的位置(即 a[i] 仍为 '1' 的位置),就是最少机器人数量。
#define _CRT_SECURE_NO_WARNINGS
#include
int main() {
    int n, c = 0;
    char str[1000];
    scanf("%d", &n);
    getchar();
    fgets(str,1000,stdin);
    for (int i = 0; i < n - 1; i++) {
        if (str[i] == '1')
        {
            str[i + 1] = '0';
        }
    }
    for (int i = 0; i < n - 1; i++) {
        if (str[i] == '1')
            c++;
    }
    printf("%d", c);
    return 0;
}
第二题

思路:

利用 “总石子数的奇偶性” 判断是否能满足条件

题目要求:

  1. 将 n 堆石子分成两部分(用两种颜色上色,即 “颜色 A” 和 “颜色 B” 两组);
  2. 两组石子的总个数 奇偶性相同(即要么都是偶数,要么都是奇数)。

我们先明确一个数学结论:两个数的奇偶性相同 ⇨ 它们的和是偶数。推导过程:

  • 偶数 + 偶数 = 偶数;
  • 奇数 + 奇数 = 偶数;
  • 偶数 + 奇数 = 奇数。

所以,设 “颜色 A” 的石子总数为 S,“颜色 B” 的石子总数为 T,题目要求等价于:S 和 T 的奇偶性相同 ⇨ S + T 是偶数

但注意:所有石子都要被上色(没有遗漏),因此 S + T = 总石子数 M。由此可推出:题目要求能否满足,等价于总石子数 M 是否为偶数

# include 
# include 
int main() {
    int n = 0, m = 0;
    scanf("%d", &n);
    int* arr = (int*)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++){
        scanf("%d", &arr[i]);
    }
    for (int i = 0; i < n; i++){
        m += arr[i];
    }
    if (m % 2 == 0) {
        printf("YES");
    }
    else {
        printf("NO");
    }
    return 0;
}
第三题

思路:

初签到题最简单的题,代数即可

#include 
#include 
#include 
double max(double a, double b) {
    return (a > b)? a : b;
}
int main() {
    int t;
    double ppmax;
    double a, b, c, d, e, f;
    scanf("%d", &t);
    while (t--) {
        double acc = 0;
        double pp = 0;
        scanf("%lf", &ppmax);
        scanf("%lf %lf %lf %lf %lf %lf", &a, &b, &c, &d, &e, &f);
        double sum = a + b + c + d + e + f;
        acc = (300.0 * a + 300.0 * b + 200.0 * c + 100.0 * d + 50.0 * e) / (300.0 * sum);
        pp = max(0.0, (320.0 * a + 300.0 * b + 200.0 * c + 100.0 * d + 50.0 * e) / (320.0 * sum) - 0.8) * 5 * ppmax;
        printf("%.2lf", acc * 100);
        printf("%% ");
        int rounded_pp = (int)((pp + 0.5000001) * 10 / 10);
        printf("%d\n", rounded_pp);
    }
    return 0;
}
第四题

思路:

将 “2024 的 b 次方 ≥ 数组所有元素乘积” 的指数不等式,转化为对数计算和整数求解

1. 利用 “数组元素是 2 的幂次方” 简化乘积计算

题目明确每个 ai = 2^kiki 是≥0 的整数),所以数组所有元素的乘积可以转化为 2 的指数求和:

  • 数组乘积 = a1 * a2 * ... * an = 2^k1 * 2^k2 * ... * 2^kn = 2^(k1 + k2 + ... + kn)
  • 设指数和为 sum_k = k1 + k2 + ... + kn,则数组乘积 = 2^sum_k

2. 转化为 “2024^b ≥ 2^sum_k” 的不等式求解

题目要求找到最小的整数 b,满足 2024^b ≥ 2^sum_k。由于对数函数是单调递增的,对不等式两边同时取自然对数(或任意底数的对数) ,不等号方向不变,可转化为:b * log(2024) ≥ sum_k * log(2)进一步变形得到:b ≥ sum_k * log(2) / log(2024)

3. 处理 “最小整数 b” 的取整逻辑

  • 计算 b_float = sum_k * log(2) / log(2024)(这是满足不等式的最小实数)
  • 若 b_float 是整数(如 b_float=2.0),则最小整数 b = b_float
  • 若 b_float 是小数(如 b_float=2.3),则最小整数 b = 整数部分 + 1(因为 2^2=4 < 2.3 对应的乘积,3^2=9 ≥ 乘积)
# include
# include 
int main() {
    int n;
    scanf("%d", &n);
    int mi_sums = 1;
    for (int i = 1; i <=n; i++){
        int m = 0;
        scanf("%d", &m);
        mi_sums += (int)log2(m);
    }
    double b = mi_sums * (log(2) / log(2024));
    int m = mi_sums * (log(2) / log(2024));
    if(b - m == 0.0)printf("%d\n", m);
    else printf("%d\n", m+1);
    return 0;
}
第五题

思路:

利用斐波那契数列的奇偶性周期规律

一、核心观察:斐波那契数列的奇偶性周期

题目中 aₙ₊₂ = aₙ₊₁ + aₙ 是斐波那契数列的定义,其每一项的 奇偶性 存在固定周期,无需计算具体数值:

  • 奇偶性的运算规则:奇 + 奇 = 偶、奇 + 偶 = 奇、偶 + 奇 = 奇、偶 + 偶 = 偶
  • 斐波那契数列的奇偶性周期为 3(即每 3 项为一个循环单元)

二、步骤 1:分析前几项的奇偶性(推导周期)

设 a₁ 的奇偶性为 p(0 = 偶,1 = 奇),a₂ 的奇偶性为 q(0 = 偶,1 = 奇),按递推公式推导前 6 项的奇偶性:

项数

奇偶性(p, q 组合)

说明

a₁

p

初始值

a₂

q

初始值

a₃

p+q(mod 2)

前两项之和的奇偶性

a₄

q + (p+q) = p(mod 2)

a₂+a₃ 的奇偶性

a₅

(p+q) + p = q(mod 2)

a₃+a₄ 的奇偶性

a₆

p + q(mod 2)

a₄+a₅ 的奇偶性

...

...

周期为 3:[p, q, p+q] 循环

结论:从 a₁ 开始,每 3 项的奇偶性会重复一次,周期长度 = 3。

三、步骤 2:计算前 n 项和的奇偶性(核心推导)

设 Sₙ = a₁ + a₂ + ... + aₙ,我们需要求 Sₙ mod 2(1 = 奇,0 = 偶)。利用周期规律,分情况计算:

先推导周期内的和的奇偶性

以一个周期(3 项)为单位,计算前 3k 项、3k+1 项、3k+2 项的和:

  • 1 个周期(3 项)的和:p + q + (p+q) = 2(p+q) ≡ 0 mod 2(偶数)

  • 前 3k 项的和:k 个周期的和,总和 ≡ 0 * k ≡ 0 mod 2(偶数)

  • 前 3k+1 项的和:3k 项和 + a₃ₖ₊₁ ≡ 0 + p ≡ p mod 2(与 a₁ 奇偶性相同)

  • 前 3k+2 项的和:3k 项和 + a₃ₖ₊₁ + a₃ₖ₊₂ ≡ 0 + p + q ≡ (p+q) mod 2(a₁+a₂ 的奇偶性)

简化 n 的判断(利用周期)

因为周期为 3,可将 n 转化为 n mod 3(余数 r=0,1,2):

  • 若 r=0 → n=3k → Sₙ ≡ 0 mod 2(偶数)

  • 若 r=1 → n=3k+1 → Sₙ ≡ p mod 2(与 a₁ 奇偶性相同)

  • 若 r=2 → n=3k+2 → Sₙ ≡ (p+q) mod 2(a₁+a₂ 的奇偶性)

四、步骤 3:按 (a₁, a₂) 奇偶性分类,直接判断结果

根据 p(a₁%2)和 q(a₂%2)的 4 种组合,结合 n mod 3 的余数,可直接得出 Sₙ 的奇偶性(这就是代码的判断逻辑):

组合 1:a₁奇(p=1)、a₂奇(q=1)

  • 余数 r=0(n=3k)→ Sₙ ≡ 0 → 0(偶)

  • 余数 r=1(n=3k+1)→ Sₙ ≡ p=1 → 1(奇)

  • 余数 r=2(n=3k+2)→ Sₙ ≡ 1+1=2≡0 → 0(偶)→ 代码逻辑:if n%3==1 → 1,else → 0

组合 2:a₁奇(p=1)、a₂偶(q=0)

  • 余数 r=0 → 0 → 0

  • 余数 r=1 → p=1 → 1

  • 余数 r=2 → 1+0=1 → 1→ 代码逻辑:if n%3==0 → 0,else → 1

组合 3:a₁偶(p=0)、a₂奇(q=1)

  • 余数 r=0 → 0 → 0

  • 余数 r=1 → p=0 → 0

  • 余数 r=2 → 0+1=1 → 1→ 代码逻辑:if n%3==2 → 1,else → 0

组合 4:a₁偶(p=0)、a₂偶(q=0)

  • 所有项均为偶(递推:偶 + 偶 = 偶),总和必为偶 → 代码逻辑:直接输出 0

#define _CRT_SECURE_NO_WARNINGS
#include
int main() {
    int t, a, b, n;
    scanf("%d", &t);
    for (int i = 0;i < t;i++) {
        scanf("%d %d %d", &a, &b, &n);
        if (a % 2 == 1 && b % 2 == 1) {
            if (n % 3 == 1) {
                printf("1\n");
            }
            else {
                printf("0\n");
            }
        }
        else if (a % 2 == 1 && b % 2 == 0) {
            if (n % 3 == 0) {
                printf("0\n");
            }
            else {
                printf("1\n");
            }
        }
        else if (a % 2 == 0 && b % 2 == 1) {
            if (n % 3 == 2) {
                printf("1\n");
            }
            else {
                printf("0\n");
            }
        }
        else {
            printf("0\n");
        }
    }
}
第六题

思路:

三维空间中 “切蛋糕” 的最大分区数问题

一、先铺垫:低维空间的 “最大分区数” 规律

在推导 3 维之前,先看更简单的 1 维(直线)、2 维(平面),找到共性规律:

1. 1 维空间(直线切线段)

  • 问题:一条直线,切 n 刀,最多分成多少段?

  • 规律:每切 1 刀,新的刀痕必须和之前所有刀痕都相交(1 维中 “相交” 就是不重合),才能新增最多区域。

    • 0 刀:1 段(初始状态)

    • 1 刀:1+1=2 段

    • 2 刀:2+2=4 段

    • 3 刀:4+3=7 段

  • 公式:f₁(n) = n(n+1)/2 + 1(或简化为 (n² +n +2)/2

2. 2 维空间(平面切饼)

  • 问题:一个平面,切 n 刀,最多分成多少块?

  • 规律:每切 1 刀,新的直线必须和之前所有直线都相交(且交点不重合),才能新增最多区域。新增的区域数 = 当前刀数(第 k 刀新增 k 块)。

    • 0 刀:1 块

    • 1 刀:1+1=2 块

    • 2 刀:2+2=4 块

    • 3 刀:4+3=7 块

    • 4 刀:7+4=11 块

  • 公式:f₂(n) = n(n+1)/2 + 1(和 1 维公式形式不同?不,展开后是 (n² +n +2)/2,和 1 维的数学形式一致,只是维度不同)

核心共性:

要得到最大分区数,每新增 1 刀(或 1 个平面),必须与之前所有的 “切割痕迹” 都相交(且交点不重合) —— 这样才能最大化利用新切割的 “分割能力”,新增最多的区域。

二、3 维空间(立体切蛋糕)—— 本题核心

蛋糕是 3 维立体(长方体 / 球体等),切割工具是 “无限大的平面”(题目说 “每次只能对立体的蛋糕产生一个切面”,即平面切割)。问题转化为:用 n 个平面切割 3 维空间,最多能分成多少个区域?

推导过程:

  1. 初始状态(0 刀):3 维空间只有 1 个区域(完整蛋糕)→ f₃(0) = 1

  2. 第 1 刀:1 个平面将 3 维空间分成 2 个区域 → f₃(1) = 2(符合样例输入 1→输出 2)

  3. 第 2 刀:要最大化分区,第 2 个平面必须与第 1 个平面相交(相交线是 1 条直线),将原有的 2 个区域各分成 2 块 → f₃(2) = 4(符合样例输入 2→输出 4)

  4. 第 3 刀:要最大化分区,第 3 个平面必须与前 2 个平面都相交(得到 2 条不重合的交线,且这 2 条交线在第 3 个平面上相交)—— 相当于在第 3 个平面上,用 2 条相交直线分成了 4 块,因此新增 4 个区域 → f₃(3) = 4 + 4 = 8(符合样例输入 3→输出 8)

  5. 第 k 刀(k≥1):第 k 个平面要与前 k-1 个平面都相交,得到 k-1 条交线。这 k-1 条交线在第 k 个平面上是 “互不平行且无三线共点” 的(满足 2 维空间最大分区的条件),因此这 k-1 条直线在第 k 个平面上能分成 f₂(k-1) 块(2 维最大分区数)。而这 f₂(k-1) 块,恰好对应 3 维空间中新增的 f₂(k-1) 个区域。

数学递推公式:

基于上述逻辑,3 维最大分区数的递推关系为:

  • f₃(0) = 1(初始状态)

  • f₃(k) = f₃(k-1) + f₂(k-1)(第 k 刀新增的区域数 = 2 维空间中 k-1 条直线的最大分区数)

代入 2 维公式化简:

已知 2 维最大分区数 f₂(k-1) = [(k-1)k)/2] + 1,代入递推公式:

f₃(n) = 1 + Σ(从k=1到n)f₂(k-1)  (累加每次新增的区域数)
      = 1 + Σ(从k=1到n)[(k-1)k/2 + 1]
      = 1 + Σ(从m=0到n-1)[m(m+1)/2 + 1]  (令m=k-1)

展开求和并化简(代数运算):

  • 先计算求和项:Σ[m(m+1)/2](m 从 0 到 n-1)= Σ(m² +m)/2 = [Σm² + Σm]/2

    • 已知求和公式:Σm(0到n-1)= n(n-1)/2Σm²(0到n-1)= n(n-1)(2n-1)/6

  • 再计算 Σ1(m 从 0 到 n-1)= n

  • 代入后整体化简,最终得到:

    f₃(n) = (n³ + 5n + 6)/6
#include 
int max_pieces(int n) {
    return (n * n * n + 5 * n + 6) / 6;
}
int main() {
    int t;
    scanf("%d", &t);
    while (t > 0) {
        int n;
        scanf("%d", &n);
        printf("%d\n", max_pieces(n));
        t--;
    }
    return 0;
}
第七题

思路:

转义字符,直接打印
下次认真看题

#include
int main(){
    printf("\"错觉没有崭新,爱经历不了久经!\"");
    return 0;
}