MENU

第七届蓝桥杯Java A——剪邮票

March 15, 2019 • Read: 4297 • 算法阅读设置

如下图, 有12张连在一起的12生肖的邮票。

现在你要从中剪下5张来,要求必须是连着的
(仅仅连接一个角不算相连)

比如


粉红色所示部分就是合格的剪取。

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

这题不能单纯用DFS来做,如果用DFS,是得不到类似"T"型格子的

正确做法是暴力枚举,从12个格子中枚举出5个格子,然后判断这5个格子是否连通,判断连通可以用DFS

import java.util.*;

public class Main {

    static boolean[] book = new boolean[13];
    static int[] path = new int[5];
    static int[][] map = new int[3][4];
    static Set<String> set = new HashSet<String>();
    static int ans;
    
    public static void main(String[] args) {
        dfs(0);
        System.out.println(ans);
    }
    
    static void dfs(int idx) {
        if (idx == 5) {
            int[] tmp = Arrays.copyOf(path, 5);
            Arrays.sort(tmp);
            String str = tmp[0] + "" + tmp[1] + "" + tmp[2] + "" + tmp[3] + "" + tmp[4];
            if (!set.contains(str) && check()) {
                set.add(str);
                System.out.println(str);
                ans++;
            }
        } else {
            for (int i = 1; i <= 12; i++) {
                if (!book[i]) {
                    book[i] = true;
                    path[idx] = i;
                    dfs(idx + 1);
                    book[i] = false;
                }
            }
        }
    }

    static boolean check() {
        map = new int[4][5];
        for (int i = 1; i <= 3; i++)
            for (int j = 1; j <= 4; j++)
                for (int t = 0; t < 5; t++)
                    if ((i - 1) * 4 + j == path[t])
                        map[i][j] = 1;
        
        // dfs check connected
        int cnt = 0;
        for (int i = 1; i <= 3; i++)
            for (int j = 1; j <= 4; j++)
                if (map[i][j] == 1) {
                    dfs_connect(i, j);
                    cnt++;
                }
        return cnt == 1;
    }

    static void dfs_connect(int i, int j) {
        map[i][j] = 0;
        if (i + 1 <= 3 && map[i + 1][j] == 1) dfs_connect(i + 1, j);
        if (j + 1 <= 4 && map[i][j + 1] == 1) dfs_connect(i, j + 1);
        if (i - 1 >= 1 && map[i - 1][j] == 1) dfs_connect(i - 1, j);
        if (j - 1 >= 1 && map[i][j - 1] == 1) dfs_connect(i, j - 1);
    }
}
Archives Tip
QR Code for this page
Tipping QR Code
Leave a Comment

3 Comments
  1. fang fang

    请问一下cnt是什么参数,有点懵逼

    1. fang fang

      @fang懂了。

  2. 菜鸡 菜鸡

    学到了@(大拇指)