【java/算法/排列】某台小型晚会由6个节目组成,演出顺序有如下要求:节目甲必须排在前两位,节目乙不能排在第一位,节目丙必须排在末位。问该台晚会演出顺序的编排方案有几种?

【题干】

某台小型晚会由6个节目组成,演出顺序有如下要求:节目甲必须排在前两位,节目乙不能排在第一位,节目丙必须排在末位。问该台晚会演出顺序的编排方案有几种?

【数学解法】

类别1:甲排首位,丙排末位,其余四个全排列,有A44种;

类别2:甲排次位,丙排末位,首位从丁戊己种选一,中间三个全排列,有C31*A33种;

Sum=A44+C31*A33=24+3*6=42种

【代码解法】

思路:将六个节目全排列,然后用三个过滤条件过滤。

主类代码:

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

import arrange.Arranger;

public class StageArrangement {
    // 测试
    public static void main(String[] args) {
        final String[] actors = { "甲", "乙", "丙", "丁", "戊", "己" };// 演员列表
        int[] arr = { 0, 1, 2, 3, 4, 5 };// 演员对应的下标数组

        Arranger arranger = new Arranger(arr);

        int idx = 0;
        for (List<Integer> argmnts : arranger.getResults()) {
            // 1.甲必須在前兩位
            if (argmnts.get(0) != 0 && argmnts.get(1) != 0) {
                continue;
            }

            // 2.乙不能在第一位
            if (argmnts.get(0) == 1) {
                continue;
            }

            // 3.丙必須在最後一位
            if (argmnts.get(5) != 2) {
                continue;
            }

            // 由脚标链表得到名称链表
            List<String> joinedNames = new ArrayList<String>(actors.length);
            for (int i = 0; i < actors.length; i++) {
                joinedNames.add(actors[argmnts.get(i)]);
            }
            String joined = String.join(",", joinedNames);

            System.out.println(String.format("%02d", ++idx) + "." + joined);
        }
    }
}

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.甲,乙,丁,戊,己,丙
02.甲,乙,丁,己,戊,丙
03.甲,乙,戊,丁,己,丙
04.甲,乙,戊,己,丁,丙
05.甲,乙,己,丁,戊,丙
06.甲,乙,己,戊,丁,丙
07.甲,丁,乙,戊,己,丙
08.甲,丁,乙,己,戊,丙
09.甲,丁,戊,乙,己,丙
10.甲,丁,戊,己,乙,丙
11.甲,丁,己,乙,戊,丙
12.甲,丁,己,戊,乙,丙
13.甲,戊,乙,丁,己,丙
14.甲,戊,乙,己,丁,丙
15.甲,戊,丁,乙,己,丙
16.甲,戊,丁,己,乙,丙
17.甲,戊,己,乙,丁,丙
18.甲,戊,己,丁,乙,丙
19.甲,己,乙,丁,戊,丙
20.甲,己,乙,戊,丁,丙
21.甲,己,丁,乙,戊,丙
22.甲,己,丁,戊,乙,丙
23.甲,己,戊,乙,丁,丙
24.甲,己,戊,丁,乙,丙
25.丁,甲,乙,戊,己,丙
26.丁,甲,乙,己,戊,丙
27.丁,甲,戊,乙,己,丙
28.丁,甲,戊,己,乙,丙
29.丁,甲,己,乙,戊,丙
30.丁,甲,己,戊,乙,丙
31.戊,甲,乙,丁,己,丙
32.戊,甲,乙,己,丁,丙
33.戊,甲,丁,乙,己,丙
34.戊,甲,丁,己,乙,丙
35.戊,甲,己,乙,丁,丙
36.戊,甲,己,丁,乙,丙
37.己,甲,乙,丁,戊,丙
38.己,甲,乙,戊,丁,丙
39.己,甲,丁,乙,戊,丙
40.己,甲,丁,戊,乙,丙
41.己,甲,戊,乙,丁,丙
42.己,甲,戊,丁,乙,丙

END

posted @ 2023-04-21 19:02  逆火狂飙  阅读(104)  评论(0编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东