第一题
思路:
利用真人判断的绝对性,反向排除 “不可能是真人” 的位置,这些位置就是最少机器人
- 优先假设所有位置是真人,但真人的判断必须正确;
- 当
a[i]='1'时,若i位是真人,i+1位必须是机器人(增加机器人数量),为了 “最少”,我们选择让i位是机器人(这样i+1位可以是真人,减少机器人); - 最终统计所有 “无法是真人” 的位置(即
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;
}
第二题
思路:
利用 “总石子数的奇偶性” 判断是否能满足条件
题目要求:
- 将 n 堆石子分成两部分(用两种颜色上色,即 “颜色 A” 和 “颜色 B” 两组);
- 两组石子的总个数 奇偶性相同(即要么都是偶数,要么都是奇数)。
我们先明确一个数学结论:两个数的奇偶性相同 ⇨ 它们的和是偶数。推导过程:
- 偶数 + 偶数 = 偶数;
- 奇数 + 奇数 = 偶数;
- 偶数 + 奇数 = 奇数。
所以,设 “颜色 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^ki(ki 是≥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 维空间,最多能分成多少个区域?
推导过程:
初始状态(0 刀):3 维空间只有 1 个区域(完整蛋糕)→
f₃(0) = 1第 1 刀:1 个平面将 3 维空间分成 2 个区域 →
f₃(1) = 2(符合样例输入 1→输出 2)第 2 刀:要最大化分区,第 2 个平面必须与第 1 个平面相交(相交线是 1 条直线),将原有的 2 个区域各分成 2 块 →
f₃(2) = 4(符合样例输入 2→输出 4)第 3 刀:要最大化分区,第 3 个平面必须与前 2 个平面都相交(得到 2 条不重合的交线,且这 2 条交线在第 3 个平面上相交)—— 相当于在第 3 个平面上,用 2 条相交直线分成了 4 块,因此新增 4 个区域 →
f₃(3) = 4 + 4 = 8(符合样例输入 3→输出 8)第 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;
}
浙公网安备 33010602011771号