【Java/算法/排列】ABCDE共5人站成一排,如果B必须站在A的右边(AB不必相邻),那么不同的排法有几种,请列举出来。

【数学解法一】

可以预设A的位置进行分类讨论:

如果A在右一,如_ _ _ _ A,那么B没地方站,这种情况排法为0;

如果A在右二,如_ _ _ A _,那么B只有1个地方可选,如_ _ _ A B,其余CDE全排,这种情况排法为A33;

如果A在正中,如_ _ A _ _,那么B有2个地方可选,其余CDE全排,这种情况排法为C21A33;

如果A在左二,如_ A _ _ _,那么B有3个地方可选,其余CDE全排,这种情况排法为C31A33;

如果A在左一,如A _ _ _ _,那么B有4个地方可选,其余CDE全排,这种情况排法为C41A33;

以上五类累计,sum=(0+1+C21+C31+C41)*A33=10*6=60种

【数学解法二】

五人全排有A55种,B在A的右侧的几率和B在左侧的几率是一样的,所以排法为A55/2=5*4*3*2*1/2=5*4*3=60种

【程序解法】

思路:五人全排,用A下标<B小标当过滤器,筛完即可。

ARightB类:

复制代码
package test230426;

import java.util.List;

import arrange.Arranger;

/**
 * ABCDE共5人站成一排,如果B必须站在A的右边(AB不必相邻),那么不同的排法有几种,请列举出来。
 */
public class ARightB {
    public static void main(String[] args) {
        final String[] names = { "A","B", "C", "D", "E" };
        final int[] arr = { 0, 1, 2, 3,4 };

        Arranger arranger = new Arranger(arr);
        int idx = 0;
        for (List<Integer> res : arranger.getResults()) {
            int posA=-1;
            int posB=-1;
            
            for(int j=0;j<res.size();j++) {
                int val=res.get(j);
                if(val==0) {
                    posA=j;
                }
                if(val==1) {
                    posB=j;
                }
            }
            
            if(posA<posB) {
                String name = "";
                for (int i = 0; i < names.length; i++) {
                    name += names[res.get(i)];
                }

                System.out.println(String.format("%02d", ++idx) + "." + name);
            }
        }
    }
}
复制代码

Arranger类:

复制代码
package arrange;

import java.util.ArrayList;
import java.util.List;

/**
 * 用于产生数组全排列结果的工具类
 * @since 2023/4/21
 */
public class Arranger {
    // 保存在内部的原始元素数组的引用
    private int[] rawArr;

    // 返回结果
    private List<List<Integer>> results;

    /**
     * 构造函数
     * 
     * @param raws 原始元素数组
     */
    public Arranger(int[] raws) {
        rawArr = raws;
        results = new ArrayList<>();

        doArrange(new ArrayList<>());
    }

    /**
     * 使用递归进行全排列,结果放在results中
     * 
     * @param initialList 初始链表
     */
    private void doArrange(List<Integer> initialList) {
        List<Integer> innerList = new ArrayList<>(initialList);

        if (rawArr.length == initialList.size()) {
            results.add(innerList);
        }

        for (int i = 0; i < rawArr.length; i++) {
            if (innerList.contains(rawArr[i])) {
                continue;
            }

            innerList.add(rawArr[i]);
            doArrange(innerList);
            innerList.remove(innerList.size() - 1);
        }
    }

    /**
     * 获得结果链表的引用
     * 
     * @return
     */
    public List<List<Integer>> getResults() {
        return results;
    }

    // 测试
    public static void main(String[] args) {
        int[] numbers = { 1, 2, 3,4,5};
        Arranger arranger = new Arranger(numbers);

        int idx = 0;
        for (List<Integer> re : arranger.getResults()) {
            System.out.println(String.format("%02d", ++idx) + "." + re);
        }
    }
}
复制代码

【输出】

复制代码
01.ABCDE
02.ABCED
03.ABDCE
04.ABDEC
05.ABECD
06.ABEDC
07.ACBDE
08.ACBED
09.ACDBE
10.ACDEB
11.ACEBD
12.ACEDB
13.ADBCE
14.ADBEC
15.ADCBE
16.ADCEB
17.ADEBC
18.ADECB
19.AEBCD
20.AEBDC
21.AECBD
22.AECDB
23.AEDBC
24.AEDCB
25.CABDE
26.CABED
27.CADBE
28.CADEB
29.CAEBD
30.CAEDB
31.CDABE
32.CDAEB
33.CDEAB
34.CEABD
35.CEADB
36.CEDAB
37.DABCE
38.DABEC
39.DACBE
40.DACEB
41.DAEBC
42.DAECB
43.DCABE
44.DCAEB
45.DCEAB
46.DEABC
47.DEACB
48.DECAB
49.EABCD
50.EABDC
51.EACBD
52.EACDB
53.EADBC
54.EADCB
55.ECABD
56.ECADB
57.ECDAB
58.EDABC
59.EDACB
60.EDCAB
复制代码

【结论】

数学两种解法和程序解法都可以相互印证。

END

posted @   逆火狂飙  阅读(214)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2022-04-26 运行期建立HikariDataSource和JdbcTemplate
2018-04-26 【js】用正则表达式对文字进行局部替换
2018-04-26 【python】用正则表达式进行文字局部替换
2018-04-26 [Python] 错误“IndentationError: unindent does not match any outer indentation level”是什么意思?
2018-04-26 【Tip】如何在chrome浏览器中查看网页的Header
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示