这是一个考察数组模拟(桶思想)和差值处理的经典题目。
解题思路
-
目标分析:
我们需要验证 个数的序列中,相邻两个数的差的绝对值,是否完整地覆盖了 到 之间的每一个整数。
-
核心步骤:
- 计算差值:遍历数组,算出相邻两数的绝对差
diff = abs(a[i] - a[i+1])。 - 标记出现:我们需要记录哪些差值已经出现过。由于差值的范围是确定的(),我们可以开一个布尔数组(或
vector<bool>)作为“桶”来标记。- 例如:如果算出差值是 3,就把
marked[3]设为true。
- 例如:如果算出差值是 3,就把
- 检查完整性:最后遍历一遍 到 ,只要发现有一个数字没被标记过,就说明不符合要求,输出
Not jolly。如果全都出现过,则输出Jolly。
- 计算差值:遍历数组,算出相邻两数的绝对差
C++ 参考代码
#include <iostream>
#include <vector>
#include <cmath> // 用于 abs() 函数
using namespace std;
int main() {
int n;
cin >> n;
// 读入数组
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
// 标记数组,用于记录差值是否出现过
// 大小设为 n 即可,下标范围 0 ~ n-1
vector<bool> has_diff(n, false);
// 计算相邻差值
for (int i = 0; i < n - 1; ++i) {
// 计算绝对值
int diff = abs(a[i] - a[i+1]);
// 我们只关心范围在 1 到 n-1 之间的差值
if (diff >= 1 && diff < n) {
has_diff[diff] = true;
}
}
// 检查 1 到 n-1 是否都存在
for (int i = 1; i < n; ++i) {
if (!has_diff[i]) {
cout << "Not jolly" << endl;
return 0; // 一旦发现缺失,直接结束程序
}
}
// 如果循环顺利结束,说明都存在
cout << "Jolly" << endl;
return 0;
}
代码解析要点
abs()函数:位于<cmath>头文件中,用于计算绝对值。- 边界判断:在标记
has_diff时,必须先判断diff是否在合法范围 内。如果差值很大(比如 ,差值为 ),直接忽略即可,因为它对“覆盖 ”没有帮助,反而直接访问数组会导致越界错误(RE)。 - 的情况:虽然题目逻辑上通常指 ,但如果输入 ,代码中的两个循环都不会执行(范围不成立),最终直接输出
Jolly,这也符合题目的隐含定义(空集覆盖空集)。