藍橋杯 剪郵票

剪郵票
 
如【圖1.jpg】, 有12張連在一塊兒的12生肖的郵票。
如今你要從中剪下5張來,要求必須是連着的。
(僅僅鏈接一個角不算相連)
好比,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。
 
請你計算,一共有多少種不一樣的剪取方法。
 
請填寫表示方案數目的整數。
 
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。java

思路:深搜找到 12 個數中 5個數的組合,而後使用廣度優先搜索判斷選出的5個是否聯通。node

錯誤思路 1:使用直接使用深度搜索,因爲深度搜索過程當中不會轉彎如下的狀況搜索不到spa

圖片來自 :https://blog.csdn.net/eventqueue/article/details/50954641.net

    2:不使用bfs判斷聯通,而是直接判斷 上下左右是否有聯通的點,如下狀況錯誤blog

             1  1  1  0圖片

      0  0  0  0it

      0  1  1  0event

代碼:class

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;
    }

}
相關文章
相關標籤/搜索