蓝桥杯 剪邮票

剪邮票
 
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
 
请你计算,一共有多少种不同的剪取方法。
 
请填写表示方案数目的整数。
 
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

思路:深搜找到 12 个数中 5个数的组合,然后使用广度优先搜索判断选出的5个是否联通。

错误思路 1:使用直接使用深度搜索,由于深度搜索过程中不会转弯以下的情况搜索不到

图片来自 :https://blog.csdn.net/eventqueue/article/details/50954641

    2:不使用bfs判断联通,而是直接判断 上下左右是否有联通的点,以下情况错误

             1  1  1  0

      0  0  0  0

      0  1  1  0

代码:

public class Stamp {

    public static int num = 0;
    public static int[] vis = new int[5];
    public static int[][] next = {{0,1},{1,0},{0,-1},{-1,0}};
    public static int[][] stamp = new int[3][4];
    public static int[] visit = new int[12];
    public static int[] have = new int[5];

    ///
    public static void main(String[] args) {
        dfs(0,0);
        System.out.println(num);
    }

    ///select five visiable number
    public static void dfs(int step,int i){
        if(step >= 5){
            if(bfs()){
                num++;
            }
            return;
        }
        for(;i<12;i++){
            if(visit[i] == 0){
                visit[i] = 1;
                have[step] = i;
                stamp[i/4][i%4] = 1;
                dfs(step+1,i+1);
                stamp[i/4][i%4] = 0;
                visit[i] = 0;
            }
        }
    }

    ///justify if accessable
    public static boolean bfs(){
        Queue<Integer> q = new LinkedList<Integer>();
        q.offer(have[0]);
        stamp[have[0]/4][have[0]%4] = -1;
        int step = 1;
        while(q.peek()!=null){
            int e = q.poll();
            for(int j=0;j<4;j++){
                int ni = e/4+next[j][0];
                int nj = e%4+next[j][1];
                if(ni<3 && ni>-1 && nj<4 && nj>-1 && stamp[ni][nj] == 1){
                    stamp[ni][nj] = -1;
                    step++;
                    q.offer(ni*4+nj);
                }
            }
        }
        /// offset
        for(int i=0;i<5;i++){
            int h = have[i];
            stamp[h/4][h%4] = 1;
        }
        return step == 5;
    }

    ///exit
    /*
    1 1 1 0 0
    0 0 0 0 0
    0 1 1 0 0
     */
    ///don't work 
    public static boolean justify(){
        //search first node
        boolean flag = false;
        for(int i=0;i<5;i++){
            // up down left right
            for(int j=0;j<4;j++){
                int ni = have[i]/4+next[j][0];
                int nj = have[i]%4+next[j][1];
                if(ni<3 && ni>-1 && nj<4 && nj>-1 && stamp[ni][nj] == 1){
                    flag = true;
                    break;
                }
            }
            if(!flag){
                return false;
            }
            else{
                flag = false;
            }

        }
        return true;
    }

}
原文地址:https://www.cnblogs.com/mxk-star/p/8672750.html