(1) 定义 Box 类。
abstract class Box {
Set<Integer> balls = new HashSet<>();
abstract boolean canAdd(int n);
boolean add(int n) {
if (!canAdd(n)) return false;
balls.add(n);
return true;
}
void remove(int n) { balls.remove(n); }
@Override public String toString() { return balls.toString(); }
}
class Box1 extends Box {
// has a capacity of 1 (only 1 integer fits into it at one time)
boolean canAdd(int n) {
return balls.size() < 1;
}
}
class Box13 extends Box {
// cannot contain 2 integers which sum up to 13
boolean canAdd(int n) {
int remain = 13 - n;
return !balls.contains(remain);
}
}
(2) 定义实际的盒子。
Box A = new Box1();
Box B = new Box13();
Box C = new Box13();
Box D = new Box13();
(3) 定义整数的偏好。
Box[][] likes = {
/* 0 */ {},
/* 1 */ {A, D},
/* 2 */ {B},
/* 3 */ {B},
/* 4 */ {B},
/* 5 */ {B},
/* 6 */ {C},
/* 7 */ {C, D},
/* 8 */ {C, D},
/* 9 */ {C, D},
/* 10 */ {C, D},
/* 11 */ {D},
};
(5) 寻找解决方案。
for (Box b1 : likes[1]) {
if (!b1.add(1)) continue;
for (Box b2 : likes[2]) {
if (!b2.add(2)) continue;
for (Box b3 : likes[3]) {
if (!b3.add(3)) continue;
for (Box b4 : likes[4]) {
if (!b4.add(4)) continue;
for (Box b5 : likes[5]) {
if (!b5.add(5)) continue;
for (Box b6 : likes[6]) {
if (!b6.add(6)) continue;
for (Box b7 : likes[7]) {
if (!b7.add(7)) continue;
for (Box b8 : likes[8]) {
if (!b8.add(8)) continue;
for (Box b9 : likes[9]) {
if (!b9.add(9)) continue;
for (Box b10 : likes[10]) {
if (!b10.add(10)) continue;
for (Box b11 : likes[11]) {
if (!b11.add(11)) continue;
System.out.printf("A=%s B=%s C=%s D=%s%n",
A, B, C, D);
b11.remove(11);
}
b10.remove(10);
}
b9.remove(9);
}
b8.remove(8);
}
b7.remove(7);
}
b6.remove(6);
}
b5.remove(5);
}
b4.remove(4);
}
b3.remove(3);
}
b2.remove(2);
}
b1.remove(1);
}
结果
A=[1] B=[2, 3, 4, 5] C=[6, 8, 9, 10] D=[7, 11]
A=[1] B=[2, 3, 4, 5] C=[6, 8, 9] D=[7, 10, 11]
A=[1] B=[2, 3, 4, 5] C=[6, 8, 10] D=[7, 9, 11]
A=[1] B=[2, 3, 4, 5] C=[6, 8] D=[7, 9, 10, 11]
A=[1] B=[2, 3, 4, 5] C=[6, 9, 10] D=[7, 8, 11]
A=[1] B=[2, 3, 4, 5] C=[6, 9] D=[7, 8, 10, 11]
A=[1] B=[2, 3, 4, 5] C=[6, 10] D=[7, 8, 9, 11]
A=[1] B=[2, 3, 4, 5] C=[6] D=[7, 8, 9, 10, 11]
A=[] B=[2, 3, 4, 5] C=[6, 8, 9, 10] D=[1, 7, 11]
A=[] B=[2, 3, 4, 5] C=[6, 8, 9] D=[1, 7, 10, 11]
A=[] B=[2, 3, 4, 5] C=[6, 8, 10] D=[1, 7, 9, 11]
A=[] B=[2, 3, 4, 5] C=[6, 8] D=[1, 7, 9, 10, 11]
A=[] B=[2, 3, 4, 5] C=[6, 9, 10] D=[1, 7, 8, 11]
A=[] B=[2, 3, 4, 5] C=[6, 9] D=[1, 7, 8, 10, 11]
A=[] B=[2, 3, 4, 5] C=[6, 10] D=[1, 7, 8, 9, 11]
A=[] B=[2, 3, 4, 5] C=[6] D=[1, 7, 8, 9, 10, 11]
递归求解器是
static void solve(Box A, Box B, Box C, Box D, Box[][] likes, int n) {
if (n > 11) {
System.out.printf("A=%s B=%s C=%s D=%s%n", A, B, C, D);
return;
}
for (Box box : likes[n]) {
if (!box.add(n)) continue;
solve(A, B, C, D, likes, n + 1);
box.remove(n);
}
}
和
solve(A, B, C, D, likes, 1);