【数学思路】
可以把题目简化成BD两人插ACE中的空缺。
当ACE三人已经拍好ACE的顺序,B插进去三人队列的4个空,D再插进去四人队列的5个空,这一类有4*5=20种情况;
当ACE三人已经拍好ECA的顺序,B插进去三人队列的4个空,D再插进去四人队列的5个空,这一类也有4*5=20种情况;
合计=20+20=40种情况。
【程序思路】
将ABCDE五人进行全排列,然后把ACE三人的序号累加到一个字符串里,如果这个字符串是ACE或是ECA则符合条件。
【代码】
辅助类Arranger:
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); }*/ } }
主类FixedLine:
import java.util.List; /** * 将ABCDE排成一列,要求ACE三人在排列中顺序为“ACE”或“ECA”,三人可以不相邻 * 列出符合条件的排列 * @author 逆火 * */ public class FixedLine { public static void main(String[] args) { final String[] names= {"A","B","C","D","E"}; int[] numbers = {0, 1, 2, 3, 4}; Arranger arranger = new Arranger(numbers); int idx = 0; for (List<Integer> line : arranger.getResults()) { String sentence=""; String order=""; for(int i:line) { if(i==0 || i==2 || i==4) { order+=i; } sentence+=names[i]+","; } if("024".equals(order) || "420".equals(order)) { System.out.println(String.format("%02d", ++idx) + "." + sentence); } } } }
【输出】
01.A,B,C,D,E, 02.A,B,C,E,D, 03.A,B,D,C,E, 04.A,C,B,D,E, 05.A,C,B,E,D, 06.A,C,D,B,E, 07.A,C,D,E,B, 08.A,C,E,B,D, 09.A,C,E,D,B, 10.A,D,B,C,E, 11.A,D,C,B,E, 12.A,D,C,E,B, 13.B,A,C,D,E, 14.B,A,C,E,D, 15.B,A,D,C,E, 16.B,D,A,C,E, 17.B,D,E,C,A, 18.B,E,C,A,D, 19.B,E,C,D,A, 20.B,E,D,C,A, 21.D,A,B,C,E, 22.D,A,C,B,E, 23.D,A,C,E,B, 24.D,B,A,C,E, 25.D,B,E,C,A, 26.D,E,B,C,A, 27.D,E,C,A,B, 28.D,E,C,B,A, 29.E,B,C,A,D, 30.E,B,C,D,A, 31.E,B,D,C,A, 32.E,C,A,B,D, 33.E,C,A,D,B, 34.E,C,B,A,D, 35.E,C,B,D,A, 36.E,C,D,A,B, 37.E,C,D,B,A, 38.E,D,B,C,A, 39.E,D,C,A,B, 40.E,D,C,B,A,
【结语】
数学方法和程序思路不同而结果又可以相互印证,可以相互证明对方的正确性。
END