dfs学习笔记 1

这篇文大概就是自己在学习过程中学到的一些模板和注意事项吧,emmm在此先膜拜各路大佬orz

先贴核心代码



void dfs()//参数用来表示状态  
{  
    if(到达终点状态)  
    {  
        ...//根据题意添加  
        return;  
    }  
    if(越界或者是不合法状态)  
        return;  
    if(特殊状态)//剪枝
        return ;
    for(扩展方式)  
    {  
        if(扩展方式所达到状态合法)  
        {  
            修改操作;//根据题意来添加  
            标记;  
            dfs();  
            (还原标记);  
            //是否还原标记根据题意  
            //如果加上(还原标记)就是 回溯法  
        }  

要注意路径记录节点重判!!!
然后接下来是一些最最最基础的dfs的题了,承蒙不弃QwQ

1.全排列
题目描述:
排列与组合是常用的数学方法。
先给一个正整数 ( 1 < = n < = 10 ) ,例如n=3,所有组合,并且按字典序输出:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
输入:
输入一个整数n(1<=n<=10)
输出:
输出所有全排列
每个全排列一行,相邻两个数用空格隔开(最后一个数后面没有空格)
样例输入:

3

样例输出:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

代码:

#include<stdio.h>
int n,a[1005];
int book[1005]={0};
void dfs(int m)
{
    if (m == n)
    {
        for(int i = 0;i<n;i++)
        {
            printf("%d",a[i]);
            if(i < n-1) printf(" ");
        }printf("\n");
        return ;
    }
    for (int i = 1;i <= n;i++)
    {
        if (book[i] == 1) continue ;
        a[m] = i;
        book[i] = 1;
        dfs(m+1);
        book[i] = 0;
    }
}
int main()
{
    scanf("%d",&n);
    dfs(0);
    return 0;
}

2,组合的输出
题目描述:
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r < = n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你不用递归的方法输出所有组合。
例如n = 5 ,r = 3 ,所有组合为:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
输入:
一行两个自然数n、r ( 1 < n < 21,1 < = r < = n )。
输出:
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,所有的组合也按字典顺序。
代码如下:

#include<stdio.h>
int m[25],n,r;
void dfs(int a,int b)
{
    if(a == r)
        {for(int i = 0;i < r;i++) printf("%d ",m[i]);
        printf("\n");}
    if(r - a >n - b + 1) return ;
    for(int i = b ;i <= n;i++)
    {
        m[a] = i; dfs(a+1,i+1);
    }
}
int main()
{
    scanf("%d %d",&n,&r);
    dfs(0,1);
    return 0;
}

先到此为止吧orz

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值