dfs模型

https://www.cnblogs.com/liushuncheng/p/6629514.html

蓝桥杯比赛关于 BFS 算法总结方法以及套路分析

首先我们来看几道java A组的题目,都是同一年的哦!!!


搭积木

小明最近喜欢搭数字积木,
一共有10块积木,每个积木上有一个数字,0~9。

搭积木规则:
每个积木放到其它两个积木的上面,并且一定比下面的两个积木数字小。
最后搭成4层的金字塔形,必须用完所有的积木。

下面是两种合格的搭法:

   0
  1 2
 3 4 5
6 7 8 9

   0
  3 1
 7 5 2
9 8 6 4   

请你计算这样的搭法一共有多少种?

请填表示总数目的数字。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

 

先帖代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

public class test4 {

    int a[]=new int[20];   //java 数组初始化值为0

       int visit[]=new int[20];  //判断是否使用过

       static int count1=0;

       public void dfs1(int x){               

           if(x==10){         

               if(a[0]<a[1]&&a[0]<a[2]        //这里没有进行剪枝操作,因为不方便

                &&a[1]<a[3]&&a[1]<a[4]&&a[2]<a[4]&&a[2]<a[5]

                &&a[3]<a[6]&&a[3]<a[7]&&a[4]<a[7]&&a[4]<a[8]&&a[5]<a[8]&&a[5]<a[9]){

                count1++;

                return;

               }

            }

            

           for(int i=0;i<10;i++){

               if(visit[i]==0){           //深度搜索套路代码,只可意会

               a[x]=i;

               visit[i]=1;

               dfs1(x+1);

               visit[i]=0;

               }

           }

           return;    //这个return是当前面的所有的都不成立时回溯(return)到最初调用for循环内的dfs处

       }

        

       public static void main(String[] args){

           new test4().dfs1(0);

           System.out.println(count1);

       }

}

  结果:768

 

题目二:


寒假作业

现在小学的数学题目也不是那么好玩的。
看看这个寒假作业:

   □ + □ = □
   □ - □ = □
   □ × □ = □
   □ ÷ □ = □
  
   (如果显示不出来,可以参见【图1.jpg】)
  
每个方块代表1~13中的某一个数字,但不能重复。
比如:
 6  + 7 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

以及:
 7  + 6 = 13
 9  - 8 = 1
 3  * 4 = 12
 10 / 2 = 5

就算两种解法。(加法,乘法交换律后算不同的方案)
 
你一共找到了多少种方案?


请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

 

 

代码:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

public class test3 {

   int a[]=new int[20];   //java 数组初始化值为0

   int visit[]=new int[20];

   static int count=0;

   public void dfs(int x){                //相当于剪枝操作

       /*if(x>3&&a[1]+a[2]!=a[3])           //如果前三个数已经被取出来但不符合题设条件,则返回重找

            return;

        if(x>6&&a[4]-a[5]!=a[6])           //若前三个数满足第一条,看4-6个数是否满足第二个条件

            return;

        if(x>9&&a[7]*a[8]!=a[9])             //同上

            return;

        if(x>12&&a[12]*a[11]==a[10])        //如果所有条件均满足,则让count++

        {

            count++;

            return;

        }*/

       if(x>12){

           if((a[1]+a[2]==a[3])&&(a[4]-a[5]==a[6])&&(a[7]*a[8]==a[9])&&(a[12]*a[11]==a[10])){

               count++;

               return;

           }

       }

       for(int i=1;i<14;i++){

           if(visit[i]==0){           //深度搜索套路代码

           a[x]=i;

           visit[i]=1;

           dfs(x+1);

           visit[i]=0;

           }

       }

       return;    //这个return是当前面的所有的都不成立时回溯(return)到最初调用for循环内的dfs处

   }

    

   public static void main(String[] args){

       new test3().dfs(1);

       System.out.println(count);

   }

    }

  结果: 64

 

第三题:


方格填数

如下的10个格子
   +--+--+--+
   |0 | 1| 2|
+--+--+--+--+
| 3| 4| 5| 6|
+--+--+--+--+
| 7| 8| 9|
+--+--+--+

(如果显示有问题,也可以参看【图1.jpg】)

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

 

代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

public class test5 {

 

    int a[]=new int[20];   //java 数组初始化值为0

       int visit[]=new int[20];  //判断是否使用过

       static int count1=0;

       public void dfs1(int x){               

           if(x==10){

               if(

                       (Math.abs(a[0]-a[1])!=1)&&

                       (Math.abs(a[0]-a[3])!=1)&&

                       (Math.abs(a[0]-a[4])!=1)&&

                       (Math.abs(a[0]-a[5])!=1)&&

                       (Math.abs(a[1]-a[2])!=1)&&

                       (Math.abs(a[1]-a[4])!=1)&&

                       (Math.abs(a[1]-a[5])!=1)&&

                       (Math.abs(a[1]-a[6])!=1)&&

                       (Math.abs(a[2]-a[5])!=1)&&

                       (Math.abs(a[2]-a[6])!=1)&&

                       (Math.abs(a[3]-a[0])!=1)&&

                       (Math.abs(a[3]-a[4])!=1)&&

                       (Math.abs(a[3]-a[7])!=1)&&

                       (Math.abs(a[3]-a[8])!=1)&&

                       (Math.abs(a[4]-a[5])!=1)&&

                       (Math.abs(a[4]-a[7])!=1)&&

                       (Math.abs(a[4]-a[8])!=1)&&

                       (Math.abs(a[4]-a[9])!=1)&&

                       (Math.abs(a[5]-a[6])!=1)&&

                       (Math.abs(a[5]-a[8])!=1)&&

                       (Math.abs(a[5]-a[9])!=1)&&

                       (Math.abs(a[6]-a[9])!=1)&&

                       (Math.abs(a[7]-a[8])!=1)&&

                       (Math.abs(a[8]-a[9])!=1)

                       ){

                   count1++;

                    return;

               }

    /*         if(a[0]!=a[1]&&a[0]!=a[3]&&a[0]!=a[4]&&a[0]!=a[5]

                       &&a[1]!=a[0]&&a[1]!=a[2]&&a[1]!=a[4]&&a[1]!=a[5]&&a[1]!=a[6]

                               &&a[2]!=a[1]&&a[2]!=a[5]&&a[2]!=a[6]

                                       &&a[3]!=a[0]&&a[3]!=a[0]&&a[3]!=a[7]

                                               &&a[4]!=a[0]&&a[4]!=a[1]&&a[4]!=a[3]&&a[4]!=a[5]&&a[4]!=a[7]&&a[4]!=a[8]&&a[4]!=a[9]

                                                       &&a[5]!=a[0]&&a[5]!=a[1]&&a[5]!=a[2]&&a[5]!=a[4]&&a[5]!=a[6]&&a[5]!=a[8]&&a[5]!=a[9]

                                                               &&a[6]!=a[1]&&a[6]!=a[2]&&a[6]!=a[5]&&a[6]!=a[9]

                                                                       &&a[7]!=a[3]&&a[7]!=a[4]&&a[7]!=a[8]

                                                                               &&a[8]!=a[3]&&a[8]!=a[4]&&a[8]!=a[5]&&a[8]!=a[7]&&a[8]!=a[9]

                                                                                       &&a[9]!=a[4]&&a[9]!=a[5]&&a[9]!=a[6]&&a[9]!=a[8]){

                count1++;

                return;

               }*/

            }

            

           for(int i=0;i<10;i++){

               if(visit[i]==0){           //深度搜索套路代码,只可意会

               a[x]=i;

               visit[i]=1;

               dfs1(x+1);

               visit[i]=0;

               }

           }

           return;    //这个return是当前面的所有的都不成立时回溯(return)到最初调用for循环内的dfs处

       }

        

       public static void main(String[] args){

           new test5().dfs1(0);

           System.out.println(count1);

       }

     

}

 

回到深度deep的时候即表示在当前深度值为num[i]的时候,后面的深度情况已全部遍历过了,然后在这深度的时候

除了前面深度所用过的数其它的数的flag[]标记都为假了,因为有了dfs(deep+1)下面的flag[i]=false这行语句,使得每回到深度deep的时候除了前面深度所用过的数其它的数的flag[]标记都为假了,当前深度的该值flag[i]标记也是为假的,然后走到for循环上面的i++为其赋上另一种可能值,下面再由deep=num[i]所以当前深度的值便可以,然后再进行下一个深度的遍历操作,至于是++还是--得由实际情况而定

 

 

 

dfs(deep+1,sum);
                //当递归的dfs除了穿深度还得传另一些参数过去的时候,就得注意递归回来时的另一参数需不需要改变回原值,一般都是需要的,
                //因为只有变回了原先前一深度的之后,然后上去i++再为现在这一深度赋上可能值,就是在这条语句下面改变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值