问题描述:
【题目描述】
给定一个整数 𝑛,将数字 1∼𝑛 排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
【输入要求】
共一行,包含一个整数 𝑛。
【输出要求】
按字典序输出所有排列方案,每个方案占一行。
【样例输入】
3
【样例输出】
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
问题分析:
这道题我们可以采用递归的方式实现。主体思路是每次确定一个数位上的数字并推进到底,到头后输出再换下一个数字进行推进。思路有些类似深度优先搜索的思路。
首先主函数部分仅需输入和调用函数。由于数字1~n的n需要重复利用,因此定义为全局变量。
int n;
int main()
{
cin>>n;
f(1);
return 0;
}
由于输出部分是在递归函数内部进行完成,因此我们的函数类型就是void空返回值类型。参数只需要一个w来记录当前的数位。
现在来确定递归边界。根据我们的思路,当每一位都确定了数字时就需要输出并从头再来,因此当w==n+1时,执行输出函数pt并return 。关于pt函数,我们待会再进行编写。
下一个部分是循环每一个数字放在当前的数位上进行尝试,为了避免数字重复,我们可以使用一个全局标记数组来记录当前使用过的数字,定义为flag。同时还需要一个数组来记录每一位上的数字进行输出,定义为a。首先判断当前遍历到的数字有没有在flag数组中被标记为1,有的话执行continue;如果没有,将flag[i]赋为1同时将a[w]赋为i。接着需要遍历下一位,执行f(w+1)。不要忘记再将flag和a的值清空。我们的程序就成功实现。
#include<iostream>
using namespace std;
int n;
int a[15],flag[15];
void pt()
{
for(int i=1;i<=n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return ;
}
void f(int w)
{
if(w==n+1)
{
pt();
return ;
}
for(int i=1;i<=n;i++)
{
if(flag[i]!=0) continue;
flag[i]=1;
a[w]=i;
f(w+1);
flag[i]=0;
a[w]=0;
}
}
int main()
{
cin>>n;
f(1);
return 0;
}
375

被折叠的 条评论
为什么被折叠?



