剪邮票
Posted zhongyimeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剪邮票相关的知识,希望对你有一定的参考价值。
(今天做的一道题。。。好累)
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
核心的就是用到了排列组合,和dfs的深度探测
public class lan_7 { private static int count = 0; private static int[] a; private static int[][] b; private static int[][] book; public static void dfs(int i, int j) { if (i > 0 && b[i - 1][j] == 1 && book[i - 1][j] == 0) { book[i - 1][j] = 1; dfs(i - 1, j); } if (i < 2 && b[i + 1][j] == 1 && book[i + 1][j] == 0) { book[i + 1][j] = 1; dfs(i + 1, j); } if (j > 0 && b[i][j - 1] == 1 && book[i][j - 1] == 0) { book[i][j - 1] = 1; dfs(i, j - 1); } if (j < 3 && b[i][j + 1] == 1 && book[i][j + 1] == 0) { book[i][j + 1] = 1; dfs(i, j + 1); } } public static boolean yshe() { boolean boo = true; for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 3; j++) { b[i][j] = a[i * 4 + j]; } } // 随便找一个点=1的 for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 3; j++) { if (b[i][j] == 1) { book[i][j] = 1; dfs(i, j); for (int ii = 0; ii <= 2; ii++) { for (int jj = 0; jj <= 3; jj++) { if (book[ii][jj] != b[ii][jj]) { boo = false; } } } break; } } } // 恢复b for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 3; j++) { b[i][j] = 0; } } // 恢复book for (int i = 0; i <= 2; i++) { for (int j = 0; j <= 3; j++) { book[i][j] = 0; } } return boo; } public static void f(int sum, int k) { if (sum == 5 && k <= 12) { // 处理每一个a,这样的话就可以得到 // 首先是将1的点映射为二维数组上的点 // 映射完还需要进行是否连通测试 if (yshe()) { count++; } return; } if (k >= 12) { return; } a[k] = 1; f(sum + 1, k + 1); a[k] = 0; f(sum, k + 1); } public static void main(String[] args) { b = new int[3][4]; book = new int[3][4]; a = new int[12]; f(0, 0); System.out.println(count); } }
结果
116
以上是关于剪邮票的主要内容,如果未能解决你的问题,请参考以下文章