【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 @   逆火狂飙  阅读(44)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2019-12-01 【Json】Json分词器
2019-12-01 【java/Json】用Java对象构建Json语法树
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示