A1636.八季之殇(AC助手题解)
2025-12-09 20:20:02
发布于:浙江
非常好!你已经写了一段功能基本正确的代码来解决这个问题,而且思路清晰。作为你的信奥教练,我将从 题目解析 → 解题逻辑分析 → 代码点评 → 时间复杂度计算 → 优化建议 这几个方面系统地帮助你。
✅ 一、深入题目解析
📌 题目大意
地球一年有12个月,4个季节(每季3个月)。
AC狗星一年有 24个月,共 8个季节,每个季节持续 3个月。
每个季节的名称依次是:新正、竹秋、建已、天中、建申、南吕、应钟、龙潜。
给出24个整数,表示狗星1月到24月的每月平均温度。
要求计算 S-Index:
对每个季节(连续3个月),计算该季节内的 最高温 - 最低温 → 得到差”;
得到8个季节温差后,找出这8个值中的 最大值和最小值;
S-Index = 这8个季节温差的最大值 - 最小值。
📥 输入描述
输入为一行,包含24个整数,表示1~24月的每月平均温度(注意:是“温度”,不是“温差”!)
⚠️ 注意:题目中说“平均温差”可能是误导性表述,根据上下文应理解为“每月的平均温度”。
📤 输出描述
输出一个整数:S-Index,即 各季节温差极差。
🔍 样例分析
输入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25
我们按每3个月分组(共8组):
季节 月份 温度序列 季节内温差(max - min)
新正 1-3 1,2,3 3 - 1 = 2
竹秋 4-6 4,5,6 6 - 4 = 2
建已 7-9 7,8,9 9 - 7 = 2
天中 10-12 10,11,12 12-10=2
建申 13-15 13,14,15 15-13=2
南吕 16-18 16,17,18 18-16=2
应钟 19-21 19,20,22 22-19=3
龙潜 22-24 23,24,25 25-23=2
所以8个季节温差为:[2,2,2,2,2,2,3,2]
→ 最大值 = 3,最小值 = 2
→ S-Index = 3 - 2 = 1
✅ 匹配样例输出:1
✅ 二、系统解题指导
✔ 步骤分解
读取数据:一共24个温度值。
分组处理:每3个一组,共8组。
对每组求极差(max - min)。
记录所有极差中的最大值与最小值。
输出最终极差之差(S-Index)。
✅ 三、代码审查与讲解
你的代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
int a, max = -1, min = 101, Mon;
for(int i = 1; i <= 8; i++) {
int maxi = -1, mini = 101;
for(int j = 1; j <= 3; j++) {
cin >> a;
if(a > maxi) maxi = a;
if(a < mini) mini = a;
}
Mon = maxi - mini;
if(Mon > max) max = Mon;
if(Mon < min) min = Mon;
}
cout << max - min;
return 0;
}
✅ 正确性评价
✔ 功能完全正确!
外层循环 i=1 to 8:处理8个季节。
内层循环 j=1 to 3:读入每个季节的3个月温度。
在每组中维护当前最大值 maxi 和最小值 mini。
计算季节温差 Mon = maxi - mini。
更新全局最大季节温差 max 和最小季节温差 min。
最终输出 max - min。
逻辑严密,没有越界或初始化错误。
⚠ 小细节提醒(非致命但可改进)
变量名风格不一致:a, Mon, max, min —— 建议统一命名规范(如全小写或驼峰)。
max 和 min 是 <algorithm> 中的函数名,虽然在这里没冲突,但在更复杂的程序中可能引发问题。建议改名为 max_season_diff, min_season_diff。
初始化合理:因为温度范围是 [0,100],所以:
初始 maxi = -1(比最小值小)
初始 mini = 101(比最大值大)
→ 安全且正确。
✅ 四、时间复杂度分析 💡(重点来了!)
🔎 什么是衡量算法运行时间随输入规模增长的变化趋势。
本题固定输入大小(24个数),但我们仍可以进行一般化分析。
🧮 具体分析你的代码
for(int i = 1; i <= 8; i++) { // 外层循环执行 8 次
for(int j = 1; j <= 3; j++) { // 内层循环执行 3 次
cin >> a;
// 两个 if 判断:O(1)
}
// 计算 Mon,并更新全局 max/min:O(1)
}
总共执行了 $ 8 \times 3 = 24 $ 次输入操作。
所有操作都是常数时间 $ O(1) O(1) $
❓为什么是 $ O(1) $?不是 $ O(n) $ 吗?
这是一个关键点!
虽然你进行了24次输入,看似像 $ O(n) $,但由于:
输入规模 固定为24,
分组数量固定为8,
每组长度固定为3,
所以整个程序的执行步数是一个 常数上限,不会随着任何变量变化。
👉 因此,在算法复杂度理论中,这种“输入规模恒定”的问题,其时间复杂度视为 常数级:$ O(1) $。
💬 补充说明:如果题目变成“给定 n 个月,每 k 个月一季”,那才是 $ O(n) $。但本题是具体数值,属于常量规模。
✅ 五、空间复杂度简析
只用了几个变量:a, maxi, mini, Mon, i, j
没有用数组存储全部数据(这是个优点!)
🟩 空间复杂度也是:$ O(1) $
你采用了 边读边处理 的策略,节省内存,适合大数据流场景。
✅ 六、进阶思考 & 优化建议(信奥拔高训练)
🔼 如果将来遇到变式题怎么办?
比如:
“给出 N 个月的温度,每 K 个月为一季,求 S-Index”
那你需要改成通用结构:
int n, k;
cin >> n >> k;
vector<int> temp(n);
for (int i = 0; i < n; ++i) cin >> temp[i];
int total_seasons = n / k;
int global_max_diff = INT_MIN, global_min_diff = INT_MAX;
for (int i = 0; i < total_seasons; ++i) {
int start = i * k;
int seg_max = temp[start], seg_min = temp[start];
for (int j = 1; j < k; ++j) {
seg_max = max(seg_max, temp[start + j]);
seg_min = min(seg_min, temp[start + j]);
}
int diff = seg_max - seg_min;
global_max_diff = max(global_max_diff, diff);
global_min_diff = min(global_min_diff, diff);
}
cout << global_max_diff - global_min_diff << endl;
此时时间复杂度为:$ O(N) $,空间复杂度 $ O(N) $
但在原题中,由于 $ N=24 $ 固定,我们不需要这么复杂。
✅ 七、总结
项目 说明
🔍 题目类型 模拟 + 枚举 + 极值处理
🧠 算法思想 分组扫描、在线维护极值
✅ 代码正确性 完全正确
⏱️ 时间复杂度 $ \boxed{O(1)} $(因输入规模固定)
💾 空间复杂度 $ \boxed{O(1)} $(未使用额外数组)
🎯 信奥考点 数据分组、边界处理、极差计算、常量复杂度认知
✅ 教练寄语 🐶
AC狗虽笨,但有你在帮它算S-Index,它一定能顺利转正!
你这段代码简洁高效,体现了良好的编程直觉。继续保持这种“边输入边处理”的意识,未来在处理大规模输入时会非常有用。
📌 记住一句话:
“当输入规模固定时,无论多少层循环,时间复杂度都可能是 $ O(1) $。”
接下来我们可以挑战一些动态分组、滑动窗口类的问题,进一步提升能力!
有问题随时来找我!💪
这里空空如也

有帮助,赞一个