【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