全排列问题(dfs)c语言
2023-12-22 11:35:17
这是一道搜索专题的基础题。
题目描述:
排列与组合是常用的数学方法。
先给一个正整数 ( 1 < = n < = 10 )
例如n=3,然后输入n个从小到大的数字,例如:1 2 3
所有组合,并且按字典序输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
输入:
输入一个整数n( 1<=n<=10)
1 2 3
输出:
输出所有全排列
每个全排列一行,相邻两个数用空格隔开(最后一个数后面没有空格)
样例输入:
3
样例输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
思路:首先我们肯定明白每个数字只能输出一次,不能多同时也不能少。即我们需要对每一次使用过的数字进行标记,从而达到不重不漏的目的。这个方面处理好了,我们再想一下如何把所有的结果准确无误的输出出来。当然,最容易想得到的就是递归(因为每找出一个数就要使用类似的步骤),比如:第一次输出1、2、3(这个结果很容易实现),但是第二个输出的是1、3、2,最好的方法就是回溯到选出2的步骤,把2换成下一位3。这样,两次结果输出就结束了,然后我们发现以1头的结果输出完了,这时我们需要回溯到选择1的时候,把1换成2,当然,第二个选择的就是1,第三个选择的就是3。这样第三个结果就是2、1、3,以此类推,,,,,,(小编在这里就不再多加赘述了)接下来我们直接来看实现这个功能的代码吧。
void dfs(int x)//x表示的是其中一种情况的第几个数
{
if(x==n)//说明该情况所需要的数都已经找到
{
for(int v=0;v<n;v++)
{
printf("%d ",d[v]);
}
printf("\n"); //输出
return ;//结束本次情况
}
else
{
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
d[x]=a[i];//对答案数组进行赋值
c[i]=1;//对选中的数进行标记,防止重复
dfs(x+1);//递归,开始下一个数字的寻找,如果该情况已经找完,则接着下面运行
c[i]=0;//清除标记,当然肯定是这个数字在这个位置的结果已经查询完毕
}
}
}
}
以上就是实现该功能的核心算法。
将它放在主函数中运行一下看看。
#include<stdio.h>
int a[10],c[10],n,d[10];//c数组对出现过的数字进行标记,d数组为记录答案的数组
void dfs(int i);
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
c[i]=0;//对计数数组进行初始化
}
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
dfs(0);
}
void dfs(int x)
{
if(x==n)
{
for(int v=0;v<n;v++)
{
printf("%d ",d[v]);
}
printf("\n");
return ;
}
else
{
for(int i=0;i<n;i++)
{
if(c[i]==0)
{
d[x]=a[i];
//printf("%d ",a[i]);
c[i]=1;
dfs(x+1);
c[i]=0;
}
}
}
}
测试样例:
3
1 2 3
输入样例:
4
1 2 3 4
?
?以上就是对全排列问题的解法,最后祝大家编程能力步步高升。
文章来源:https://blog.csdn.net/weixin_63617665/article/details/123459839
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!