【高中数学/排列组合】甲乙丙丁戊五名同学站成一排参加文艺汇演,若甲不站在两端,丙和丁相邻,则不同的排列方式共有多少种?(2022全国新高考II卷)

【问题】

甲乙丙丁戊五名同学站成一排参加文艺汇演,若甲不站在两端,丙和丁相邻,则不同的排列方式共有多少种?

A.12种

B.24种

C.36种

D.48种

【答案】

B

【出处】

2022全国新高考II卷第5题单选题,五分

【解答】

首先把丙丁捆绑,然后让甲、乙、丙丁、戊四组人全排列有A(4,4)*2=48种排法,这是总数;

其次把甲放在首位,乙、丙丁、戊三组人全排列A(3,3)*2=12种排法;

再次把甲放在末位,乙、丙丁、戊三组人全排列A(3,3)*2=12种排法;

结果为48-12-12=24种。

【程序解法】

主类:

package test251121;

import java.util.List;

/**
 * 【高中数学/排列组合】
 * 甲乙丙丁戊五名同学站成一排参加文艺汇演,
 * 若甲不站在两端,丙和丁相邻,则不同的排列方式共有多少种?
 * (2022全国新高考II卷第五题)
 *
 */
public class Test251121 {
    public static void main(String[] args) {
        String[] names= {"甲","乙","丙","丁","戊",};// 名称数组
        int[] idxs= {0,1,2,3,4};// 下标数组
        
        Arranger arger = new Arranger(idxs,idxs.length);
        int sn=0;
        for (List<Integer> line : arger.getResults()) {
            // 甲不在队首或者队尾
            if(line.get(0)==0 || line.get(4)==0) {                
                continue;
            }        
            
            // 丙丁必须捆绑
            int bingIdx=-1;
            int dingIdx=-1;
            for(int i=0;i<5;i++) {
                if(line.get(i)==2) {
                    bingIdx=i;// 取丙位置
                }else if(line.get(i)==3) {
                    dingIdx=i;// 取丁位置
                }
            }
            if(Math.abs(bingIdx-dingIdx)!=1) {
                // 丙丁位置相差不为1则不算
                continue;
            }
            
            // 获得排列方案
            String order="";
            for(int i=0;i<5;i++) {
                order+=names[line.get(i)];
            }
            
            // 输出
            System.out.println((++sn)+"."+order);
        }
    }
}

全排列类:

package test251121;

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);
        }*/
    }
}

 

【程序输出】

1.乙甲丙丁戊
2.乙甲丁丙戊
3.乙甲戊丙丁
4.乙甲戊丁丙
5.乙丙丁甲戊
6.乙丁丙甲戊
7.乙戊甲丙丁
8.乙戊甲丁丙
9.丙丁甲乙戊
10.丙丁甲戊乙
11.丙丁乙甲戊
12.丙丁戊甲乙
13.丁丙甲乙戊
14.丁丙甲戊乙
15.丁丙乙甲戊
16.丁丙戊甲乙
17.戊甲乙丙丁
18.戊甲乙丁丙
19.戊甲丙丁乙
20.戊甲丁丙乙
21.戊乙甲丙丁
22.戊乙甲丁丙
23.戊丙丁甲乙
24.戊丁丙甲乙

【点评】

这题成不了刺客只是送分题。

END

posted @ 2019-12-01 11:25  逆火狂飙  阅读(593)  评论(0)    收藏  举报