【Java/算法/排列】ABCDE共5人站成一排,如果B必须站在A的右边(AB不必相邻),那么不同的排法有几种,请列举出来。
【数学解法一】
可以预设A的位置进行分类讨论:
如果A在右一,如_ _ _ _ A,那么B没地方站,这种情况排法为0;
如果A在右二,如_ _ _ A _,那么B只有1个地方可选,如_ _ _ A B,其余CDE全排,这种情况排法为A33;
如果A在正中,如_ _ A _ _,那么B有2个地方可选,其余CDE全排,这种情况排法为C21A33;
如果A在左二,如_ A _ _ _,那么B有3个地方可选,其余CDE全排,这种情况排法为C31A33;
如果A在左一,如A _ _ _ _,那么B有4个地方可选,其余CDE全排,这种情况排法为C41A33;
以上五类累计,sum=(0+1+C21+C31+C41)*A33=10*6=60种
【数学解法二】
五人全排有A55种,B在A的右侧的几率和B在左侧的几率是一样的,所以排法为A55/2=5*4*3*2*1/2=5*4*3=60种
【程序解法】
思路:五人全排,用A下标<B小标当过滤器,筛完即可。
ARightB类:
package test230426; import java.util.List; import arrange.Arranger; /** * ABCDE共5人站成一排,如果B必须站在A的右边(AB不必相邻),那么不同的排法有几种,请列举出来。 */ public class ARightB { public static void main(String[] args) { final String[] names = { "A","B", "C", "D", "E" }; final int[] arr = { 0, 1, 2, 3,4 }; Arranger arranger = new Arranger(arr); int idx = 0; for (List<Integer> res : arranger.getResults()) { int posA=-1; int posB=-1; for(int j=0;j<res.size();j++) { int val=res.get(j); if(val==0) { posA=j; } if(val==1) { posB=j; } } if(posA<posB) { String name = ""; for (int i = 0; i < names.length; i++) { name += names[res.get(i)]; } System.out.println(String.format("%02d", ++idx) + "." + name); } } } }
Arranger类:
package arrange; import java.util.ArrayList; import java.util.List; /** * 用于产生数组全排列结果的工具类 * @since 2023/4/21 */ public class Arranger { // 保存在内部的原始元素数组的引用 private int[] rawArr; // 返回结果 private List<List<Integer>> results; /** * 构造函数 * * @param raws 原始元素数组 */ public Arranger(int[] raws) { rawArr = raws; results = new ArrayList<>(); doArrange(new ArrayList<>()); } /** * 使用递归进行全排列,结果放在results中 * * @param initialList 初始链表 */ private void doArrange(List<Integer> initialList) { List<Integer> innerList = new ArrayList<>(initialList); if (rawArr.length == initialList.size()) { results.add(innerList); } for (int i = 0; i < rawArr.length; i++) { if (innerList.contains(rawArr[i])) { continue; } innerList.add(rawArr[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,5}; Arranger arranger = new Arranger(numbers); int idx = 0; for (List<Integer> re : arranger.getResults()) { System.out.println(String.format("%02d", ++idx) + "." + re); } } }
【输出】
01.ABCDE 02.ABCED 03.ABDCE 04.ABDEC 05.ABECD 06.ABEDC 07.ACBDE 08.ACBED 09.ACDBE 10.ACDEB 11.ACEBD 12.ACEDB 13.ADBCE 14.ADBEC 15.ADCBE 16.ADCEB 17.ADEBC 18.ADECB 19.AEBCD 20.AEBDC 21.AECBD 22.AECDB 23.AEDBC 24.AEDCB 25.CABDE 26.CABED 27.CADBE 28.CADEB 29.CAEBD 30.CAEDB 31.CDABE 32.CDAEB 33.CDEAB 34.CEABD 35.CEADB 36.CEDAB 37.DABCE 38.DABEC 39.DACBE 40.DACEB 41.DAEBC 42.DAECB 43.DCABE 44.DCAEB 45.DCEAB 46.DEABC 47.DEACB 48.DECAB 49.EABCD 50.EABDC 51.EACBD 52.EACDB 53.EADBC 54.EADCB 55.ECABD 56.ECADB 57.ECDAB 58.EDABC 59.EDACB 60.EDCAB
【结论】
数学两种解法和程序解法都可以相互印证。
END
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2022-04-26 运行期建立HikariDataSource和JdbcTemplate
2018-04-26 【js】用正则表达式对文字进行局部替换
2018-04-26 【python】用正则表达式进行文字局部替换
2018-04-26 [Python] 错误“IndentationError: unindent does not match any outer indentation level”是什么意思?
2018-04-26 【Tip】如何在chrome浏览器中查看网页的Header