【Java/math/排列组合】有8位学生,其中小学生2名,初中生3名,高中生3名,现将他们排成一列,要求2名小学生相邻,3名初中生相邻,3名高中生任意两名都不相邻,则不同排法有几种?

【题目】

有8位学生,其中小学生2名,初中生3名,高中生3名,现将他们排成一列,要求2名小学生相邻,3名初中生相邻,3名高中生任意两名都不相邻,则不同排法有几种?

【数学解答】

三高全排:A33=6

两小全排:A22=2

三初全排:A33=6

两小捆绑和三初捆绑插三高间的两空:C22A22=2

合计:6*2*6*2=144种

【代码解答】

辅助类:Arranger

package test230901;

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

/**
 * 用于产生排列结果的工具类
 * 从n个元素中取出m个元素,按照一定的顺序排成一列。得到所有排列的方案
 */
public 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);
        }
    }
}

主类 SpringTour:

package test230901;

import java.util.List;

/**
 * 有8位学生,其中小学生2名,初中生3名,高中生3名,
 * 现将他们排成一列,要求:
 * 2名小学生相邻,3名初中生相邻,3名高中生任意两名都不相邻.
 * 则不同排法有几种?
 * @author 逆火
 *
 */
public class SpringTour {
    public static void main(String[] args) {
        // 八人名单
        final String[] members= {" 高A "," 高B "," 高C "," 初一 "," 初二 "," 初三 "," 小1 "," 小2 "};
        
        // 八人对应的脚标
        int[] arr = {0,1,2,3,4,5,6,7};
        
        // 全排列器
        Arranger a1=new Arranger(arr);
        
        StringBuilder sb;// 用作组合最终名单
        int idx=0;// 用作下标
        for (List<Integer> ls : a1.getResults()) {
            // 过滤一:高中生互不相邻
            String first=members[ls.get(0)];
            String last =members[ls.get(7)];
            String middle=members[ls.get(3)]+""+members[ls.get(4)];
            if(first.contains("高")==false || 
                    last.contains("高")==false ||
                    middle.contains("高")==false) {
                continue;
            }
            
            String second=members[ls.get(1)];
            if(second.contains("小")) {
                // 第二个是小学生,第三个必须是小学生
                String third=members[ls.get(2)];
                if(third.contains("小")==false) {
                    continue;
                }else {
                    // 两小学生的话,第四个必须是高中生
                    String fourth=members[ls.get(3)];
                    if(fourth.contains("高")==false) {
                        continue;
                    }
                }
            }else if(second.contains("初")) {
                // 第二个是初中生,第三个必须是初中生
                String third=members[ls.get(2)];
                String fourth=members[ls.get(3)];
                
                if(third.contains("初")==false || fourth.contains("初")==false) {
                    continue;
                }
            }else {
                continue;
            }
            
            // 组合最终名单字串
            sb=new StringBuilder();
            sb.append(String.format("%03d.", ++idx));
            for(int i:ls) {
                sb.append(members[i]);
            }
            
            // 打印最终名单
            System.out.println(sb.toString());
            sb=null;
        }
    }
}

【运行结果】

001. 高A  初一  初二  初三  高B  小1  小2  高C 
002. 高A  初一  初二  初三  高B  小2  小1  高C 
003. 高A  初一  初二  初三  高C  小1  小2  高B 
004. 高A  初一  初二  初三  高C  小2  小1  高B 
005. 高A  初一  初三  初二  高B  小1  小2  高C 
006. 高A  初一  初三  初二  高B  小2  小1  高C 
007. 高A  初一  初三  初二  高C  小1  小2  高B 
008. 高A  初一  初三  初二  高C  小2  小1  高B 
009. 高A  初二  初一  初三  高B  小1  小2  高C 
010. 高A  初二  初一  初三  高B  小2  小1  高C 
011. 高A  初二  初一  初三  高C  小1  小2  高B 
012. 高A  初二  初一  初三  高C  小2  小1  高B 
013. 高A  初二  初三  初一  高B  小1  小2  高C 
014. 高A  初二  初三  初一  高B  小2  小1  高C 
015. 高A  初二  初三  初一  高C  小1  小2  高B 
016. 高A  初二  初三  初一  高C  小2  小1  高B 
017. 高A  初三  初一  初二  高B  小1  小2  高C 
018. 高A  初三  初一  初二  高B  小2  小1  高C 
019. 高A  初三  初一  初二  高C  小1  小2  高B 
020. 高A  初三  初一  初二  高C  小2  小1  高B 
021. 高A  初三  初二  初一  高B  小1  小2  高C 
022. 高A  初三  初二  初一  高B  小2  小1  高C 
023. 高A  初三  初二  初一  高C  小1  小2  高B 
024. 高A  初三  初二  初一  高C  小2  小1  高B 
025. 高A  小1  小2  高B  初一  初二  初三  高C 
026. 高A  小1  小2  高B  初一  初三  初二  高C 
027. 高A  小1  小2  高B  初二  初一  初三  高C 
028. 高A  小1  小2  高B  初二  初三  初一  高C 
029. 高A  小1  小2  高B  初三  初一  初二  高C 
030. 高A  小1  小2  高B  初三  初二  初一  高C 
031. 高A  小1  小2  高C  初一  初二  初三  高B 
032. 高A  小1  小2  高C  初一  初三  初二  高B 
033. 高A  小1  小2  高C  初二  初一  初三  高B 
034. 高A  小1  小2  高C  初二  初三  初一  高B 
035. 高A  小1  小2  高C  初三  初一  初二  高B 
036. 高A  小1  小2  高C  初三  初二  初一  高B 
037. 高A  小2  小1  高B  初一  初二  初三  高C 
038. 高A  小2  小1  高B  初一  初三  初二  高C 
039. 高A  小2  小1  高B  初二  初一  初三  高C 
040. 高A  小2  小1  高B  初二  初三  初一  高C 
041. 高A  小2  小1  高B  初三  初一  初二  高C 
042. 高A  小2  小1  高B  初三  初二  初一  高C 
043. 高A  小2  小1  高C  初一  初二  初三  高B 
044. 高A  小2  小1  高C  初一  初三  初二  高B 
045. 高A  小2  小1  高C  初二  初一  初三  高B 
046. 高A  小2  小1  高C  初二  初三  初一  高B 
047. 高A  小2  小1  高C  初三  初一  初二  高B 
048. 高A  小2  小1  高C  初三  初二  初一  高B 
049. 高B  初一  初二  初三  高A  小1  小2  高C 
050. 高B  初一  初二  初三  高A  小2  小1  高C 
051. 高B  初一  初二  初三  高C  小1  小2  高A 
052. 高B  初一  初二  初三  高C  小2  小1  高A 
053. 高B  初一  初三  初二  高A  小1  小2  高C 
054. 高B  初一  初三  初二  高A  小2  小1  高C 
055. 高B  初一  初三  初二  高C  小1  小2  高A 
056. 高B  初一  初三  初二  高C  小2  小1  高A 
057. 高B  初二  初一  初三  高A  小1  小2  高C 
058. 高B  初二  初一  初三  高A  小2  小1  高C 
059. 高B  初二  初一  初三  高C  小1  小2  高A 
060. 高B  初二  初一  初三  高C  小2  小1  高A 
061. 高B  初二  初三  初一  高A  小1  小2  高C 
062. 高B  初二  初三  初一  高A  小2  小1  高C 
063. 高B  初二  初三  初一  高C  小1  小2  高A 
064. 高B  初二  初三  初一  高C  小2  小1  高A 
065. 高B  初三  初一  初二  高A  小1  小2  高C 
066. 高B  初三  初一  初二  高A  小2  小1  高C 
067. 高B  初三  初一  初二  高C  小1  小2  高A 
068. 高B  初三  初一  初二  高C  小2  小1  高A 
069. 高B  初三  初二  初一  高A  小1  小2  高C 
070. 高B  初三  初二  初一  高A  小2  小1  高C 
071. 高B  初三  初二  初一  高C  小1  小2  高A 
072. 高B  初三  初二  初一  高C  小2  小1  高A 
073. 高B  小1  小2  高A  初一  初二  初三  高C 
074. 高B  小1  小2  高A  初一  初三  初二  高C 
075. 高B  小1  小2  高A  初二  初一  初三  高C 
076. 高B  小1  小2  高A  初二  初三  初一  高C 
077. 高B  小1  小2  高A  初三  初一  初二  高C 
078. 高B  小1  小2  高A  初三  初二  初一  高C 
079. 高B  小1  小2  高C  初一  初二  初三  高A 
080. 高B  小1  小2  高C  初一  初三  初二  高A 
081. 高B  小1  小2  高C  初二  初一  初三  高A 
082. 高B  小1  小2  高C  初二  初三  初一  高A 
083. 高B  小1  小2  高C  初三  初一  初二  高A 
084. 高B  小1  小2  高C  初三  初二  初一  高A 
085. 高B  小2  小1  高A  初一  初二  初三  高C 
086. 高B  小2  小1  高A  初一  初三  初二  高C 
087. 高B  小2  小1  高A  初二  初一  初三  高C 
088. 高B  小2  小1  高A  初二  初三  初一  高C 
089. 高B  小2  小1  高A  初三  初一  初二  高C 
090. 高B  小2  小1  高A  初三  初二  初一  高C 
091. 高B  小2  小1  高C  初一  初二  初三  高A 
092. 高B  小2  小1  高C  初一  初三  初二  高A 
093. 高B  小2  小1  高C  初二  初一  初三  高A 
094. 高B  小2  小1  高C  初二  初三  初一  高A 
095. 高B  小2  小1  高C  初三  初一  初二  高A 
096. 高B  小2  小1  高C  初三  初二  初一  高A 
097. 高C  初一  初二  初三  高A  小1  小2  高B 
098. 高C  初一  初二  初三  高A  小2  小1  高B 
099. 高C  初一  初二  初三  高B  小1  小2  高A 
100. 高C  初一  初二  初三  高B  小2  小1  高A 
101. 高C  初一  初三  初二  高A  小1  小2  高B 
102. 高C  初一  初三  初二  高A  小2  小1  高B 
103. 高C  初一  初三  初二  高B  小1  小2  高A 
104. 高C  初一  初三  初二  高B  小2  小1  高A 
105. 高C  初二  初一  初三  高A  小1  小2  高B 
106. 高C  初二  初一  初三  高A  小2  小1  高B 
107. 高C  初二  初一  初三  高B  小1  小2  高A 
108. 高C  初二  初一  初三  高B  小2  小1  高A 
109. 高C  初二  初三  初一  高A  小1  小2  高B 
110. 高C  初二  初三  初一  高A  小2  小1  高B 
111. 高C  初二  初三  初一  高B  小1  小2  高A 
112. 高C  初二  初三  初一  高B  小2  小1  高A 
113. 高C  初三  初一  初二  高A  小1  小2  高B 
114. 高C  初三  初一  初二  高A  小2  小1  高B 
115. 高C  初三  初一  初二  高B  小1  小2  高A 
116. 高C  初三  初一  初二  高B  小2  小1  高A 
117. 高C  初三  初二  初一  高A  小1  小2  高B 
118. 高C  初三  初二  初一  高A  小2  小1  高B 
119. 高C  初三  初二  初一  高B  小1  小2  高A 
120. 高C  初三  初二  初一  高B  小2  小1  高A 
121. 高C  小1  小2  高A  初一  初二  初三  高B 
122. 高C  小1  小2  高A  初一  初三  初二  高B 
123. 高C  小1  小2  高A  初二  初一  初三  高B 
124. 高C  小1  小2  高A  初二  初三  初一  高B 
125. 高C  小1  小2  高A  初三  初一  初二  高B 
126. 高C  小1  小2  高A  初三  初二  初一  高B 
127. 高C  小1  小2  高B  初一  初二  初三  高A 
128. 高C  小1  小2  高B  初一  初三  初二  高A 
129. 高C  小1  小2  高B  初二  初一  初三  高A 
130. 高C  小1  小2  高B  初二  初三  初一  高A 
131. 高C  小1  小2  高B  初三  初一  初二  高A 
132. 高C  小1  小2  高B  初三  初二  初一  高A 
133. 高C  小2  小1  高A  初一  初二  初三  高B 
134. 高C  小2  小1  高A  初一  初三  初二  高B 
135. 高C  小2  小1  高A  初二  初一  初三  高B 
136. 高C  小2  小1  高A  初二  初三  初一  高B 
137. 高C  小2  小1  高A  初三  初一  初二  高B 
138. 高C  小2  小1  高A  初三  初二  初一  高B 
139. 高C  小2  小1  高B  初一  初二  初三  高A 
140. 高C  小2  小1  高B  初一  初三  初二  高A 
141. 高C  小2  小1  高B  初二  初一  初三  高A 
142. 高C  小2  小1  高B  初二  初三  初一  高A 
143. 高C  小2  小1  高B  初三  初一  初二  高A 
144. 高C  小2  小1  高B  初三  初二  初一  高A 

END

posted @ 2022-12-01 16:44  逆火狂飙  阅读(41)  评论(1编辑  收藏  举报
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东