两个乒乓球队进行比赛,各出三人。甲队为 a, b, c 三人,乙队为 x, y, z 三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a 说他不和 x 比,c 说他不和 x、z 比,请编程序找出两队赛手的名单。
这是一道典型的逻辑推理与排列组合问题,目标是根据给定的约束条件,找出甲队三人(a, b, c)分别对阵乙队三人(x, y, z)的一一对应关系(即一个双射:每人对一人,且不重复)。
已知约束条件:
a ≠ x(a 不和 x 比)
c ≠ x 且 c ≠ z(c 只能和 y 比)
由于每人都必须有唯一对手,且乙队三人也必须全部被分配,因此这是一个在全排列中筛选满足条件的匹配的问题。
a vs z
b vs x
c vs y问题本质:在集合 {x, y, z} 的所有排列中,找出满足以下条件的排列 (p₀, p₁, p₂),使得:
p₀ ≠ 'x' (a 的对手不是 x)
p₂ ≠ 'x' 且 p₂ ≠ 'z' (c 的对手不是 x 或 z)
全排列共 3! = 6 种,枚举如下:
public class TableTennisMatch {
public static void main(String[] args) {
char[] teamA = {'a', 'b', 'c'};
char[] teamB = {'x', 'y', 'z'};
// 遍历 teamB 的所有排列(i, j, k 互不相同)
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (j == i) continue;
for (int k = 0; k < 3; k++) {
if (k == i || k == j) continue;
// 当前对阵:a->teamB[i], b->teamB[j], c->teamB[k]
char aOpp = teamB[i];
char bOpp = teamB[j];
char cOpp = teamB[k];
// 检查约束条件
if (aOpp != 'x' && cOpp != 'x' && cOpp != 'z') {
System.out.println("a vs " + aOpp);
System.out.println("b vs " + bOpp);
System.out.println("c vs " + cOpp);
}
}
}
}
}
}a vs z
b vs x
c vs y此类问题属于约束满足问题,常用于逻辑编程、人工智能入门教学。
在实际编程中,若规模更大(如 10 人对 10 人),需使用回溯算法或匈牙利算法等更高效方法。
本题虽小,但体现了排列生成 + 条件过滤的经典编程思维。
类似经典问题还有:“谁养鱼?”(爱因斯坦谜题)、“八皇后问题”等。