每日c/c++题 备战蓝桥杯(全排列问题)

题目描述

按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

输入格式

一个整数 n。

输出格式

由 1∼n 组成的所有不重复的数字序列,每行一个序列。

每个数字保留 5 个场宽。

输入输出样例

输入 #1

复制代码
3

输出 #1

复制代码
    1    2    3
    1    3    2
    2    1    3
    2    3    1
    3    1    2
    3    2    1

说明/提示

1≤n≤9。

解题思路

问题分析

全排列问题是一个经典的递归问题。我们需要生成 1 到 n 的所有排列,且每个排列中的数字不能重复。为了实现这一点,可以使用深度优先搜索(DFS)算法,通过回溯法逐步构建排列。

思路解析

  1. **DFS(深度优先搜索)**:
  • 使用 DFS 逐步构建排列,每次选择一个未使用的数字加入当前排列。

  • 当排列的长度 n达到 时,输出该排列。

  1. **回溯法**:
  • 在每次递归调用中,标记当前选择的数字为已使用(`hx[i] = 1`)。

  • 递归完成后,回溯并取消标记(`hx[i] = 0`),以便尝试其他可能的排列。

  1. **标记数组**:
  • 使用一个标记数组 `hx` 来记录每个数字是否已经被使用,避免重复选择。

算法步骤

  1. 初始化一个标记数组 `hx`,用于记录每个数字是否被使用。

  2. 定义一个递归函数 `dfs(x)`,其中 `x` 表示当前排列的长度。

  3. 在递归函数中:

  • 如果 `x` 等于 n,说明已经生成了一个完整的排列,输出该排列。

  • 否则,遍历所有可能的数字(1 到 n),选择未使用的数字加入当前排列,并递归调用 `dfs(x+1)`。

  • 递归返回后,取消标记,以便尝试其他数字。

代码实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n;
int d[15]={0};
int hx[15]={0};
void dfs(int x)
{
	if(x == n) //可以输出
	{
		for(int i=0;i<n;++i)
		printf("%5d",d[i]);
		printf("\n");
	 } 
	for(int i=0;i<n;++i)
	{
		if(hx[i] == 0)
		{
			hx[i] = 1;
			d[x] = i + 1; 
			dfs(x+1);
			hx[i] = 0;
		}
	}
}
int main()
{

	cin>>n;
	
	dfs(0);
	
	return 0;
}

总结

这道题目是一个典型的全排列问题,使用 DFS 和回溯法可以高效地生成所有排列。通过标记数组避免重复选择数字,确保生成的排列符合要求。DFS 的递归结构清晰,适合解决类似的问题。

相关推荐
f狐0狸x2 小时前
【蓝桥杯每日一题】4.1
c语言·c++·算法·蓝桥杯
ん贤2 小时前
2023第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组(真题&题解)(C++/Java题解)
java·c语言·数据结构·c++·算法·蓝桥杯
梭七y2 小时前
【力扣hot100题】(022)反转链表
算法·leetcode·链表
威视锐科技5 小时前
软件定义无线电36
网络·网络协议·算法·fpga开发·架构·信息与通信
牧歌悠悠5 小时前
【Python 算法】动态规划
python·算法·动态规划
JINX的诅咒5 小时前
CORDIC算法:三角函数的硬件加速革命——从数学原理到FPGA实现的超高效计算方案
算法·数学建模·fpga开发·架构·信号处理·硬件加速器
二进制人工智能5 小时前
【QT5 网络编程示例】TCP 通信
网络·c++·qt·tcp/ip
明天不下雨(牛客同名)6 小时前
为什么 ThreadLocalMap 的 key 是弱引用 value是强引用
java·jvm·算法
lisw057 小时前
DeepSeek原生稀疏注意力(Native Sparse Attention, NSA)算法介绍
人工智能·深度学习·算法
喝拿铁写前端8 小时前
SmartField AI:让每个字段都找到归属!
前端·算法