【高中数学/排列组合】将ABCDE排成一列,要求ACE三人在排列中顺序为“ACE”或“ECA”,三人可以不相邻,请列出符合条件的排列

【问题】

将ABCDE排成一列,要求ACE三人在排列中顺序为“ACE”或“ECA”,三人可以不相邻,请列出符合条件的排列

【出处】

不详

【数学思路】

可以把题目简化成BD两人插ACE中的空缺。

当ACE三人已经拍好ACE的顺序,B插进去三人队列的4个空,D再插进去四人队列的5个空,这一类有4*5=20种情况;

当ACE三人已经拍好ECA的顺序,B插进去三人队列的4个空,D再插进去四人队列的5个空,这一类也有4*5=20种情况;

合计=20+20=40种情况。

【程序思路】

将ABCDE五人进行全排列,然后把ACE三人的序号累加到一个字符串里,如果这个字符串是ACE或是ECA则符合条件。

【代码】

辅助类Arranger:

复制代码
import java.util.ArrayList;
import java.util.List;

/**
 * 用于产生排列结果的工具类
 * 从n个元素中取出m个元素,按照一定的顺序排成一列。得到所有排列的方案
 */
class Arranger {
    // 保存在内部的对原始元素数组的引用
    private int[] arr;

    // 总计多少元素,此即数组长度
    private final int n;

    // 选多少个
    private final int m;

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

    /**
     * 构造函数一
     * 这个构造函数是用于全排列的(n=m=数组长度)
     *
     * @arr 原始元素数组
     */
    public Arranger(int[] arr) {
        this.arr = arr;
        this.n = arr.length;
        this.m = arr.length;

        this.results = new ArrayList<>();
        doArrange(new ArrayList<>());
    }

    /**
     * 构造函数二
     * 这个构造函数是用于部分排列的(m<n=数组长度)
     *
     * @param arr    原始元素数组
     * @param selCnt 选多少个
     */
    public Arranger(int[] arr, int selCnt) {
        this.arr = arr;
        this.n = arr.length;
        this.m = selCnt;
        if (m > n) {
            throw new ArrayIndexOutOfBoundsException("m:" + m + " >n:" + n);
        }

        this.results = new ArrayList<>();
        doArrange(new ArrayList<>());
    }

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

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

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

            innerList.add(arr[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};
        Arranger arranger = new Arranger(numbers);

        System.out.println("四元素全排列示例:");
        int idx = 0;
        for (List<Integer> re : arranger.getResults()) {
            System.out.println(String.format("%02d", ++idx) + "." + re);
        }

        /*Arranger arranger2 = new Arranger(numbers, 2);
        System.out.println("\n四选二排列示例:");
        idx = 0;
        for (List<Integer> re : arranger2.getResults()) {
            System.out.println(String.format("%02d", ++idx) + "." + re);
        }*/
    }
}
复制代码

主类FixedLine:

复制代码
import java.util.List;

/**
 * 将ABCDE排成一列,要求ACE三人在排列中顺序为“ACE”或“ECA”,三人可以不相邻
 * 列出符合条件的排列
 * @author 逆火
 *
 */
public class FixedLine {
    public static void main(String[] args) {
        final String[] names= {"A","B","C","D","E"};
        int[] numbers = {0, 1, 2, 3, 4};
        Arranger arranger = new Arranger(numbers);

        int idx = 0;
        for (List<Integer> line : arranger.getResults()) {
            
            String sentence="";
            String order="";
            for(int i:line) {
                if(i==0 || i==2 || i==4) {
                    order+=i;
                }
                
                sentence+=names[i]+",";
            }
            
            if("024".equals(order) || "420".equals(order)) {
                System.out.println(String.format("%02d", ++idx) + "." + sentence);
            }
        }
    }
}
复制代码

【程序输出】

复制代码
01.A,B,C,D,E,
02.A,B,C,E,D,
03.A,B,D,C,E,
04.A,C,B,D,E,
05.A,C,B,E,D,
06.A,C,D,B,E,
07.A,C,D,E,B,
08.A,C,E,B,D,
09.A,C,E,D,B,
10.A,D,B,C,E,
11.A,D,C,B,E,
12.A,D,C,E,B,
13.B,A,C,D,E,
14.B,A,C,E,D,
15.B,A,D,C,E,
16.B,D,A,C,E,
17.B,D,E,C,A,
18.B,E,C,A,D,
19.B,E,C,D,A,
20.B,E,D,C,A,
21.D,A,B,C,E,
22.D,A,C,B,E,
23.D,A,C,E,B,
24.D,B,A,C,E,
25.D,B,E,C,A,
26.D,E,B,C,A,
27.D,E,C,A,B,
28.D,E,C,B,A,
29.E,B,C,A,D,
30.E,B,C,D,A,
31.E,B,D,C,A,
32.E,C,A,B,D,
33.E,C,A,D,B,
34.E,C,B,A,D,
35.E,C,B,D,A,
36.E,C,D,A,B,
37.E,C,D,B,A,
38.E,D,B,C,A,
39.E,D,C,A,B,
40.E,D,C,B,A,
复制代码

【结语】

数学方法和程序思路不同而结果又可以相互印证,可以相互证明对方的正确性。

END

posted @   逆火狂飙  阅读(343)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2013-09-02 【Canvas与艺术】红色纵横田字结
2013-09-02 【Canvas与诗词】欲买桂花同载酒,终不似,少年游
2013-09-02 Linux防火墙配置
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示