$题解 P1157 【组合的输出】$

[$ P1157 \ \text{组合的输出}\(](https://www.luogu.org/problem/P1157) 一道\)DFS$和回溯算法的入门练手好题。
还是比较简单的,注释都在代码里,自己看吧。

#include<bits/stdc++.h> //万能头
using namespace std;
int m,n,s[100];  //s[]用来标记数
bool vis[100]; //vis[]表示一个数是否可以使用,1表示可以使用,0表示不能使用
void dfs(int k)  //dfs深搜
{
    if(k==n+1)  //前n个位置都填过了
    {
        for(int j=1;j<=n;j++)
        cout<<setw(3)<<s[j];    //将填入的数依次输出
        cout<<endl;  //换行
        return ;  //结束本次调用
    }
    for(int i=s[k-1];i<=m;i++)  //将每个数遍历一遍,注意,后一个数要大于前一个数,所以i要从s[k-1]开始遍历
    {
        if(vis[i])  //如果i这个数还没有使用
        {           //就使用它
            s[k]=i;  //将i这个数填入s数组中
            vis[i]=0;  //标记i这个数已经使用过了
            dfs(k+1);  //调用下一层
            vis[i]=1; //回溯,标记i这个数还未使用
        }
    }
}
int main()
{
    s[0]=1; //初始化,不然dfs(1)时,for循环无法工作
    memset(vis,1,sizeof(vis));   //将vis数组全部标为可以使用
    cin>>m>>n;  //输入
    dfs(1);  //从第一个数开始搜索
}

还是来点小解释吧,每\(dfs\)一次,都将往\(a\)数组填一个数,直到\(k==n+1\)为止,那为何不是\(n\)呢,因为当\(k==n\),程序是在填第\(n\)个数,所以,还没有搜索完。至于其他的代码里说的都很清楚,好了,本题解就这样结了。


posted @ 2019-08-13 14:00  Luke·Skywalker  阅读(175)  评论(0)    收藏  举报