如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
public class Main {
private static int mp[] = { 1, 2, 3, 4,
6, 7, 8, 9,
11, 12, 13, 14
};
private static int aa[] = new int[5]; //记录选择的五个节点
private static int vis[] = new int[5]; //记录节点是否被访问
private static int sum = 0; //保存结果
private static int b[] = {-1, 1, -5, +5}; //用来计算是否是相邻
public static void main(String[] args) {
//下面这样的多层循环不就完成了12个数里面选5个数吗,这里的循环变量是下标
for (int a = 0; a < 12; a++)
for (int b = a + 1; b < 12; b++)
for (int c = b + 1; c < 12; c++)
for (int d = c + 1; d < 12; d++)
for (int e = d + 1; e < 12; e++) {
//这里将选择的5个下标所对应的值给aa数组
aa[0] = mp[a];
aa[1] = mp[b];
aa[2] = mp[c];
aa[3] = mp[d];
aa[4] = mp[e];
//初始化所有的节点为没有访问
for (int i = 0; i < 5; i++) {
vis[i] = 0;
}
vis[0] = 1; //将第一个节点设置为已经访问
dfs(0); //从第一个节点开始进行dfs
int flag = 1;
for (int i = 0; i < 5; i++) {
//如果存在访问数组中有 为 0 的值,即这次选择的5个数不符合题意
if (vis[i] != 1) {
flag = 0;
break;
}
}
if (flag == 0) continue;
else{ //说明visit数组里面的所有值为1,五个节点符合题意
sum++;
}
}
System.out.println(sum);
}
public static void dfs(int n) { //dfs方法,传入从哪个节点开始进行访问
for (int i = 0; i < 4; i++) { //因为只有4种可能,左右,上下
int t = aa[n] + b[i];
if (t < 1 || t > 14 || t == 5 || t == 10) continue; //这些是不可能存在的点
for (int j = 0; j < 5; j++)
if (!(vis[j] == 1) && aa[j] == t) { //如果并没有访问这个节点,并且判断出来j节点和n节点是相邻的
vis[j] = 1; //符合条件,使得设置为已经访问
dfs(j); //然后从这个节点进行dfs
}
}
}
}