1 条题解
-
0
📝 题目大意
有 个整数 排成一列,其中有 个"レ"连接相邻整数(第 个"レ"连接 与 )。阅读规则:每次选取未读的最小整数 ,找到包含 的连通分量,将该分量内所有整数从大到小读出。求最终的阅读顺序。
💡 解题思路
-
题目分析:
- ,数据范围极小, 甚至 均可通过。
- 由于"レ"只连接相邻整数( 与 ),图的连通分量必然是原序列上连续的一段区间。这是简化问题的关键隐藏条件。
- 当按"每次选最小未读数"操作时,等价于从左到右处理每个连通块,每个块内部从大到小输出。
-
算法推导:
- 用一个布尔数组
a[110]标记:a[x] = 1表示 与 之间有一条"レ"边。 - 从左到右扫描 ,用变量
s记录当前连续"レ"的个数(即当前连通块中边的数量):- 若
a[i] == 1:说明 与 属于同一连通块,s++。 - 若
a[i] == 0:说明当前连通块在 处结束,该块的范围是 (共 个元素),从 倒序输出到 ;然后s = 0重置。
- 若
- 举例: 时,
a[1]=a[3]=a[4]=1。扫描到 (a[2]=0)时 ,输出 ;扫描到 时 ,输出 。
- 用一个布尔数组
-
边界与细节:
- :
a数组全为 ,每个 都触发输出, 始终为 ,输出 自身,即 。代码自然处理。 - 相邻"レ"连续(如 ): 会累加到 ,在 处一次性输出 ,正确。
- 注意数组大小:,开到 足够。
- :
⏱️ 复杂度分析
- 时间复杂度:,仅需一次线性扫描。
- 空间复杂度:,仅需一个标记数组。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; int n, m, x, s, z, a[110]; int main(){ cin >> n >> m; // 标记"レ"的位置:a[x]=1 表示 x 与 x+1 之间有一条边 for(int i = 0; i < m; i++){ cin >> x; a[x] = 1; } // 从左到右扫描,s 表示当前连通块中连续边的数量 for(int i = 1; i <= n; i++){ if(a[i] != 0) s++; // 边还在延续,累加 else{ // 当前连通块到此结束,范围 [i-s, i],倒序输出 for(int j = i; j >= i - s; j--){ cout << j << " "; } s = 0; // 重置,准备下一个连通块 } } return 0; } -
- 1
信息
- ID
- 680
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者