PTA小字辈(BFS)

本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。

输入格式:

输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。

输出格式:

首先输出最小的辈分(老祖宗的辈分为 1,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。

输入样例:

9
2 6 5 5 -1 5 6 4 7

输出样例:

4
1 9

其实主要是存储的数据结构的设计。

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<list>
#include<set>
#include<cmath>
using namespace std;
typedef long long ll;
struct node
### PTA 小费拼图 BFS算法 实现与解法 #### 问题分析 小费拼图通常涉及在一个二维网格中移动特定的元素以达到某种目标状态。此类问题可以通过广度优先搜索(BFS)求解,因为它能够找到从初始状态到目标状态的最短路径[^1]。 在该问题中,假设我们有一个大小为 `N×M` 的棋盘,某些位置可能有障碍物或其他特殊条件。我们需要通过一系列合法操作将初始状态转换为目标状态。每一步的操作可以定义为上下左右四个方向之一的移动。为了确保效率,我们可以利用队列来存储当前的状态以及到达该状态所需的步数[^2]。 以下是基于BFS的小费拼图解决方案的具体实现: --- #### 解决方案设计 ##### 数据结构的选择 - **队列 (Queue)**:用于保存待处理的状态及其对应的步数。 - **集合 (Set)** 或者布尔数组 (**Visited Array**):记录已经访问过的状态,防止重复计算。 ##### 状态表示 每个状态可以用字符串或者其他唯一标识符来描述整个棋盘的情况。例如,对于一个简单的 `3x3` 棋盘,可以直接将其展平成一维字符串 `"12345678."` 表示空白格的位置和其他数字排列情况。 ##### 边界条件 需注意以下边界条件: - 如果起点就是终点,则无需任何移动即可完成任务。 - 若无法抵达目标状态(如存在不可逾越的障碍),则返回 `-1` 或其他标志值表明无解。 --- #### Python代码实现 下面提供了一个通用版本的Python程序框架,适用于大多数类似的滑动谜题问题: ```python from collections import deque def bfs_puzzle(start, target): # 定义可行动作:左移、右移、上移、下移 moves = [(0,-1),(0,1),(-1,0),(1,0)] n = int(len(start) ** 0.5) # 假设输入是一维化后的方阵 queue = deque([(start, 0)]) # 初始化队列为[(当前状态, 步数)] visited = set([start]) # 记录已访问过状态 while queue: current_state, steps = queue.popleft() if current_state == target: # 找到了目标状态 return steps index_of_empty = current_state.index('.') # 获取空位索引 row, col = divmod(index_of_empty, n) # 转换为空位坐标 for dr, dc in moves: # 遍历所有可行动作 new_r, new_c = row + dr, col + dc if not (0 <= new_r < n and 0 <= new_c < n): continue # 判断是否越界 swap_index = new_r * n + new_c # 新位置的一维索引 swapped_list = list(current_state) # 字符串转列表以便修改 swapped_list[index_of_empty], swapped_list[swap_index] = \ swapped_list[swap_index], swapped_list[index_of_empty] next_state = ''.join(swapped_list) if next_state not in visited: # 只扩展未访问的新状态 visited.add(next_state) queue.append((next_state, steps + 1)) return -1 # 如果穷尽所有可能性仍未找到解 # 测试用例 if __name__ == "__main__": start = "12345678." goal = ".87654321" result = bfs_puzzle(start, goal) print(f"Minimum number of moves required is {result}") ``` 此段代码实现了基本的功能需求并考虑了一些常见的优化措施,比如只允许有效的交换操作进入下一步探索阶段等[^3]。 --- #### 时间复杂度分析 由于每次仅改变单一字符形成新状态,并且只有当尚未见过这种配置才会加入等待序列之中;因此理论上讲,在理想情况下其时间消耗应接近线性增长关系相对于总节点数目而言。具体来说,如果把每一个独一无二的局面看做一个独立个体的话,那么整体运行耗时大致相当于 O(V+E),其中 V 是顶点数量而 E 则代表边的数量[^4]。 --- ####
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值