package A类有价值的回顾的;
import java.util.Arrays;
import java.util.HashSet;
/*
0 1 2 3
4 5 6 7
8 9 10 11
http://www.cnblogs.com/loveluking/p/6390455.html
*/
public class 剪邮票 {
private static boolean[] b = new boolean[12];
private static int[] c = new int[5];
private static HashSet<String> cc = new HashSet<String>();
private static int[] fa(int cur){//各种情况枚举出来速度还是可以的
//可以改成这样的public static int[][] s = {{},{2,5},{1,6,3},{2,7,4},{3,8},{1,6,9},{2,5,7,10},{3,6,8,11},{4,7,12},{5,10},{9,6,11},{10,7,12},{8,11}};
//能第零个开始就第零个开始吧,要不然会混乱,程序员嘛
if(cur == 0) {int[] s = {1,4}; return s;}
if(cur == 1) {int[] s = {0,5,2}; return s;}
if(cur == 2) {int[] s = {1,6,3}; return s;}
if(cur == 3) {int[] s = {2,7}; return s;}
if(cur == 4) {int[] s = {0,5,8}; return s;}
if(cur == 5) {int[] s = {1,4,6,9}; return s;}
if(cur == 6) {int[] s = {2,5,7,10}; return s;}
if(cur == 7) {int[] s = {3,6,11}; return s;}
if(cur == 8) {int[] s = {4,9}; return s;}
if(cur == 9) {int[] s = {5,8,10}; return s;}
if(cur == 10) {int[] s = {6,9,11}; return s;}
if(cur == 11) {int[] s = {7,10}; return s;}
else
return null;
}
private static void f(int a){
if(a == 5){//a ==6一定是错误的,明白吗,因为a是从0开始的,所以进入下一层判断就是5
int[] e = new int[5];
for(int l=0;l<5;l++){
e[l] = c[l];
}
Arrays.sort(e);//为什么不能对c直接进行排序,一定要注意,这将会对数组发生改变,而且没有回溯,影响其他分支的计算
String s = Arrays.toString(e);//都是Arrays里面的应用方法
System.out.println(s);
cc.add(s);
return;//没有return也是不行的,没有return会导致继续往下进行
}
if(a == 0){//没有这一段也不行,因为只有下面的话a=0,i<0将一个都不会执行
for(int l=0;l<12;l++){
if(b[l] == false){
c[a] = l;
b[l] = true;
f(a+1);
b[l] = false;
}
}
}
else{
for(int i=0; i<a; i++){
int[] d = fa(c[i]);//return available int array
for(int j=0;j<d.length;j++){
if(b[d[j]] == false){
c[a] = d[j];
b[d[j]] = true;
f(a+1);
b[d[j]] = false;
}
}
}
}
}
public static void main(String[] args) {
f(0);
System.out.println(cc.size());
}
}
/*
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
*/
剪邮票.java
最新推荐文章于 2021-05-03 16:34:13 发布