dfs---之全排列

如何模拟出5个人站在一排所有站法?写出一个5层循环好像就可以了,但是如果是n个人呢,我们不可能每次写一个n层循环。但是深度优先搜索,可以很容易实现这个问题。 
输入:每次给定一个n,代表n个人,n个人编号是从1到n 

输出:模拟所有站法。

代码:

//用搜索实现全排列。
#include<cstdio>
#include<cstring>
//#include<stack> 
#include<algorithm>
using namespace std;
void dfs(int i);
const int maxn = 100;
int num[maxn];
int map[maxn];
int cop[maxn];
//stack<int> a;
int ans,n;
int main()
{
    while(~scanf("%d",&n))          //n个人 
    {
        for(int i=1;i<=n;++i)       
        {
            num[i]=i;               //第i个人的编号设置为i 
            map[i]=1;               
        }
        dfs(1);                     //从第一开始搜索 
        printf("%d\n",ans);
        ans=0; 
    }
    return 0;
}
void dfs(int i)
{
    if(i==n+1)                      //搜索到 n+1个人的时候停止搜索 
    {
        for(int i=1;i<=n;++i)
        {
            printf("%d ",cop[i]);   
        }
        printf("\n");
        ans++;
        return ;
    }
    for(int j=1;j<=n;++j)           
    {
        if(map[j]==1)
        {
            map[j]=0;
            cop[i]=num[j];  
            dfs(++i);
            i--;
            map[j]=1;
        }
    }
}

/*以上属于转载*/

这个题之后我在想,如果随便给你你个数组实现全排列呢?

#include<iostream>  
#include<algorithm>  
using namespace std;  
int n,a[15]={0},v[15]={0};  
void dfs(int s)  
{  
    int i,j;  
    for (i=1;i<=n;i++)  
    {  
        if (!v[i])  //该位置没有赋过值  
        {  
            v[i]=1;  //为1,代表该位置赋过值的  
            a[s]=i;  
            if (s<n)  
              dfs(s+1);//列举下一个数   
            else  
             {  
                for (j=1;j<=n;j++) //生成一个排列   
                 cout<<a[j]<<" ";  
                cout<<endl;  
              }   
            v[i]=0; //重新设置成未访问   
         }   
    }  
}  
int main()  
{  
    cin>>n;  
    dfs(1);  
    return 0;  
}

但是好像还没有办法解决数组中有相同元素的问题,这个问题现在我还没有解决,以后会更新的

posted @ 2018-03-06 07:26  Nlifea  阅读(124)  评论(0编辑  收藏  举报