剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
解析:这个题很迷,不是很懂,但是代码是没问题的,基本思路就是从1-12里面回溯选出5个数,然后再检验5个数是否可以连通。选出5个数来当然不难,暴力循环可以,当然回溯也可以,这里采用暴力,蓝桥杯的题目能用暴力解的很多。而检测连通性,需要建立一个vis[]数组来判断,定住一个数,如果到其他各点能够连通则执行递归继续判断,当全部可连通时,vis[]数组全为true,总数+1。而如果这个点不是4或者8的时候,就每次+1递归;如果出现4和8,则每次+4递归。这是因为4和8是不能继续走到5和9的。最终结果为116。
public class Main {static int a[] = new int[5]; public static void main(String[] args) { int count = 0; for (a[0] = 0; a[0] < 12; a[0]++) { for (a[1] = a[0] + 1; a[1] < 12; a[1]++) { for (a[2] = a[1] +1 ; a[2] < 12; a[2]++) { for (a[3] = a[2]+1; a[3] < 12; a[3]++) { for (a[4] = a[3]+1; a[4] < 12; a[4]++) { if (judge()) { count++; } } } } } } System.out.println(count); }
// 检测连通性private static boolean judge() { boolean visit[] = new boolean[5]; dfs(visit,0); return visit[0]&&visit[1]&&visit[2]&&visit[3]&&visit[4]; }
// dfsprivate static void dfs(boolean[] visit, int i) { visit[i] = true; for (int j = 0; j < visit.length; j++) { // 不是4和8的时候 if (!visit[j] && (a[i]/4==a[j]/4) && (a[i]==a[j]+1 || a[i]==a[j]-1)) { dfs(visit, j); } // 是4和8的时候if (!visit[j] && (a[i] == a[j]+4 || a[i]==a[j]-4)) { dfs(visit, j); } } }
}