源本科技 | 码上会

乒乓球队比赛对阵

2026/01/26
8
0

题目

两个乒乓球队进行比赛,各出三人。甲队为 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

👈点击左箭头查看答案(一定要在自己思考并实现后再看参考答案哦!)

规律分析

  1. 问题本质:在集合 {x, y, z} 的所有排列中,找出满足以下条件的排列 (p₀, p₁, p₂),使得:

    • p₀ ≠ 'x' (a 的对手不是 x)

    • p₂ ≠ 'x' 且 p₂ ≠ 'z' (c 的对手不是 x 或 z)

  2. 全排列共 3! = 6 种,枚举如下:

a

b

c

是否合法

x

y

z

❌ a≠x, c≠z

x

z

y

❌ a≠x

y

x

z

❌ c≠z

y

z

x

❌ c≠x

z

x

y

✅ 满足所有条件

z

y

x

❌ c≠x


程序实现

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 人),需使用回溯算法或匈牙利算法等更高效方法。

  • 本题虽小,但体现了排列生成 + 条件过滤的经典编程思维。

类似经典问题还有:“谁养鱼?”(爱因斯坦谜题)、“八皇后问题”等。