逐个计算相邻差值,用集合判重并检查差值是否落在 1 到 n-1。
OJ: luogu
题目 ID: P1152
难度:入门
标签:模拟集合python
日期: 2026-06-18 23:50
题意
给定一个长度为 n 的整数序列。如果相邻元素差的绝对值恰好包含 1,2,...,n-1,就称它为 Jolly。
判断输入序列是否满足这个条件。
思路
把所有相邻差值看成要收集的数字。
对每一对相邻元素计算:
text
diff = abs(a[i + 1] - a[i])合法的 diff 必须满足两个条件:
- 在
1..n-1之间; - 没有出现过。
如果某个差值越界或重复,就一定不是 Jolly。如果所有相邻差值都通过检查,因为一共有 n-1 个差值,它们就正好组成 1..n-1 的一个排列。
Python 知识
abs(x)直接计算绝对值。set()用来记录已经出现过的差值,diff in seen是判重。print("Jolly" if ok else "Not jolly")是条件表达式,适合二选一输出。- 本题输入换行位置不重要,可以用
sys.stdin.buffer.read()按 token 读取。
参考笔记:
/home/rainboy/mycode/hugo-blog/content/program_language/python/collections_toolkit.md/home/rainboy/mycode/hugo-blog/content/program_language/python/math_tools.md/home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md
代码
python
import sys
data = list(map(int, sys.stdin.buffer.read().split()))
n = data[0]
numbers = data[1:1 + n]
seen = set()
ok = True
for i in range(n - 1):
diff = abs(numbers[i + 1] - numbers[i])
if diff < 1 or diff >= n or diff in seen:
ok = False
break
seen.add(diff)
print("Jolly" if ok else "Not jolly")Pythonic 写法
集合判定 Jolly:
python
import sys
data = list(map(int, sys.stdin.buffer.read().split()))
n, a = data[0], data[1:1 + data[0]]
diffs = []
ok = True
seen = set()
for i in range(n - 1):
d = abs(a[i + 1] - a[i])
if d < 1 or d >= n or d in seen:
ok = False
break
seen.add(d)
print('Jolly' if ok and len(seen) == n - 1 else 'Not jolly')复杂度
时间复杂度为
总结
这题的关键不是排序,而是把条件拆成“范围合法”和“没有重复”两个检查。