DFS2016年蓝桥杯省赛java剪邮票

如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。

请你计算,一共有多少种不同的剪取方法。

请填写表示方案数目的整数。

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

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

public class Main {
    private static int mp[] = { 1,  2,  3,  4, 
    						    6,  7,  8,  9,
    						    11, 12, 13, 14
    						  };
    
    private static int aa[] = new int[5];  //记录选择的五个节点
    private static int vis[] = new int[5]; //记录节点是否被访问
    private static int sum = 0;              //保存结果
    private static int b[] = {-1, 1, -5, +5}; //用来计算是否是相邻

    public static void main(String[] args) {
    	
    	//下面这样的多层循环不就完成了12个数里面选5个数吗,这里的循环变量是下标
        for (int a = 0; a < 12; a++)
        	
            for (int b = a + 1; b < 12; b++)
            	
                for (int c = b + 1; c < 12; c++)
                	
                    for (int d = c + 1; d < 12; d++)
                    	
                        for (int e = d + 1; e < 12; e++) {
                        	
                        	//这里将选择的5个下标所对应的值给aa数组
                            aa[0] = mp[a];
                            aa[1] = mp[b];
                            aa[2] = mp[c];
                            aa[3] = mp[d];
                            aa[4] = mp[e];
                            
                            //初始化所有的节点为没有访问
                            for (int i = 0; i < 5; i++) {
                                vis[i] = 0;
                            }
                            
                            vis[0] = 1; //将第一个节点设置为已经访问
                            
                            dfs(0);     //从第一个节点开始进行dfs
                            
                            int flag = 1;
                            for (int i = 0; i < 5; i++) {
                            	
                            	//如果存在访问数组中有 为 0 的值,即这次选择的5个数不符合题意
                                if (vis[i] != 1) {
                                    flag = 0;
                                    break;
                                }
                            }
                            
                            if (flag == 0) continue;
                            else{  //说明visit数组里面的所有值为1,五个节点符合题意
                                sum++;
                            }
                        }
        
        System.out.println(sum);
    }

    public static void dfs(int n) {  //dfs方法,传入从哪个节点开始进行访问
    	
        for (int i = 0; i < 4; i++) {  //因为只有4种可能,左右,上下
        	
            int t = aa[n] + b[i];
            
            if (t < 1 || t > 14 || t == 5 || t == 10) continue; //这些是不可能存在的点
            
            for (int j = 0; j < 5; j++)
            	
                if (!(vis[j] == 1) && aa[j] == t) {  //如果并没有访问这个节点,并且判断出来j节点和n节点是相邻的
                	
                    vis[j] = 1; //符合条件,使得设置为已经访问
                    
                    dfs(j);    //然后从这个节点进行dfs
                }
        }
    }
}

















猜你喜欢

转载自blog.csdn.net/weixin_42036647/article/details/88378631
今日推荐