【日耕一题】7. 循环右移(2026第17届蓝桥杯C++B组省赛 C 题)

你好,我是林森lsjs

我的Github 地址:sqyCoder (Qiyang) · GitHub

以博文记录成长,用心打磨代码与思维

欢迎来到日耕一题,今天这道是 2026 蓝桥杯省赛的 C 题,

纯思维题。抓住任意连续子数组这个强约束

一、题目完整解读

原题

试题 C: 循环右移

时间限制: 1.0s 内存限制: 256.0MB 本题总分:10 分

给定三个整数 N,X,Y。请计算有多少个长度为 N 的整数数组 A 满足以下条件:

  1. 数组 A 中的每个元素 A_i 都满足 X ≤ A_i ≤ Y;
  2. 对于数组 A 中的任意一个连续子数组,对其进行一次循环右移操作,得到的新子数组与原数组完全一致。

循环右移:对一个长度为 k 的连续子数组 [B₁,B₂,…,B_k] 执行一次循环右移操作,是指将该子数组变换为 [B_k,B₁,B₂,…,B_{k-1}](即把最后一个元素移到最开头,其余元素保持原有顺序依次向后顺延一位)。

输入格式第一行包含一个整数 T,表示测试数据的组数。接下来的 T 行,每行包含三个由空格隔开的整数 N,X,Y。

输出格式对于每组测试数据,输出一行,包含一个整数,表示满足条件的数组 A 的个数。

拆解所有要求

  1. 数组长度固定为 N,每个元素取值在 [X, Y] 之间
  2. 强约束:所有连续子数组,循环右移一次后必须和自身完全相同
  3. 输出合法数组的总个数
  4. 数据范围极大:N、X、Y 均可达到 10¹⁸,普通循环、数组模拟完全不可行

N 是迷惑项,最终结果和数组长度完全无关

X 可能大于 Y,此时没有合法元素,答案为 0

数值范围远超 int,必须用 long 类型

二、核心推导:条件到底意味着什么?

很多人读完题第一反应是去想长数组的循环右移性质,其实完全不用搞那么复杂。

约束越强,结论越极端—— 既然要求任意连续子数组都满足,那我们从最小的子数组入手,就能推出全局性质。

1. 从最小子数组切入:长度为 2 的情况

我们随便取数组中任意两个相邻元素,组成长度为 2 的连续子数组:[a, b]。对它执行一次循环右移,得到的结果是[b, a]

题目要求操作后与原数组完全一致,也就是:

[b, a] = [a, b]

对应位置相等,必然有a = b

这说明什么?数组中任意两个相邻元素都必须相等。相邻相等可以传递:a₁=a₂,a₂=a₃ → a₁=a₃。以此类推,整个数组所有元素都必须相等。

2. 充分性验证:全相等数组必然满足

反过来,如果一个数组所有元素都相等,那它是否满足条件?

显然成立。任意取一个连续子数组,里面每个元素都一样,循环右移之后元素还是那些,顺序怎么换都和原数组完全相同。

3. 最终结论

长度为 N 的数组满足条件,当且仅当数组中所有元素都相等

因此问题直接简化为:在 [X, Y] 范围内选一个数,作为数组所有元素的值,一共有多少种选法?答案就是区间内整数的个数:Y - X + 1(当 X ≤ Y 时);如果 X > Y,答案为 0。

划重点:最终结果和 N 没有任何关系,不管 N 是 1 还是 10¹⁸,答案都一样。这是题目最大的迷惑项。

三、易错坑点与数据范围说明

坑 1:被 N 带偏思路

很多同学上来就盯着 N 想组合数、想排列,算来算去越算越复杂。其实只要沉下心推一遍性质,就会发现 N 完全没用,读进来不用处理就行。

坑 2:忽略 X > Y 的情况

如果输入的 X 比 Y 大,说明取值区间是空的,合法元素个数为 0,答案就是 0。直接写y - x + 1会得到负数,提交直接错。

坑 3:数据类型溢出

题目里 X、Y 可以到 10¹⁸,远超 int 的 21 亿上限,必须用long类型存储和计算。Java 中输入的常量也要注意用 long 接收。

四、完整可运行代码(Java)

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int T = sc.nextInt(); while (T-- > 0) { // 注意:全部用long类型,N读进来但不需要使用 long N = sc.nextLong(); long X = sc.nextLong(); long Y = sc.nextLong(); if (X > Y) { System.out.println(0); } else { System.out.println(Y - X + 1); } } sc.close(); } }

代码核心逻辑只有一行判断加计算,剩下的都是输入输出。哪怕 T 有 1000 组、数据到 10¹⁸,也能瞬间算出结果。

五、样例输入输出全复盘

我们拿官方样例来验证一遍:

输入样例

3 3 1 2 5 10 10 2 5 3

逐组计算

  1. 第一组:N=3,X=1,Y=2 → 区间内有 1、2 两个数 → 输出 2
  2. 第二组:N=5,X=10,Y=10 → 只有 10 一个数 → 输出 1
  3. 第三组:N=2,X=5,Y=3 → X>Y,区间为空 → 输出 0

输出样例

2 1 0

和预期完全一致。

六、总结~

这道题是非常经典的「算法思维题」,不考代码实现,不考数据结构,就考你能不能沉下心从基础条件推导性质,不被题干的复杂描述吓住。

核心思路:

  1. 遇到任意子数组都满足某性质,先从最短的子数组入手,推导全局约束
  2. 验证充要性,确保结论反过来也成立
  3. 忽略迷惑参数,抓住核心计算式
  4. 注意数据范围和边界情况,避免溢出和负数答案

就到这里,诸位共勉!