【Java/算法/排列】用数字0,1,2,3,4,5,6组成没有重复数字的四位数,其中个位、十位和百位上的数字之和为偶数的四位数共有几个?
【数学解法】
千位分两种情况:
当千位为135之一,假设为1,剩下023456给个十百位
若十百位为两奇数一偶数,则有C22C41A33;
若十百位为三偶数,则有C43A33;
当千位为246之一,假设为2,剩下013456给个十百位
若十百位为两奇数一偶数,则有C32C31A33;
若十百位为三偶数,则有C33A33;
所以,总数=3*(24+24+54+6)=3*108=324种
【程序解法】
思路:将0,1,2,3,4,5,6选4进行排列,去除掉首位为0和个十百位之和不是偶数的,剩下的就是结果。
主类EvenSum代码:
package test230501; import test230429.Arranger; import java.util.List; /** * 用数字0,1,2,3,4,5,6组成没有重复数字的四位数,其中个位、十位和百位上的数字之和为偶数的四位数共有几个? */ public class EvenSum { public static void main(String[] args){ int[] numbers = {0,1, 2, 3, 4,5,6}; Arranger arranger = new Arranger(numbers,4); int idx = 0; for (List<Integer> re : arranger.getResults()) { // 去掉千位为0的情况 if(re.get(0)==0){ continue; } // 去掉百十个三位和为奇数的情况 int sum=re.get(1)+re.get(2)+re.get(3); if((sum % 2)==1){ continue; } System.out.println(String.format("%02d", ++idx) + "." + re.get(0)+re.get(1)+re.get(2)+re.get(3)); } } }
辅助类Arranger:
package test230429; 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); } } }
输出:
01.1024 02.1026 03.1035 04.1042 05.1046 06.1053 07.1062 08.1064 09.1204 10.1206 11.1235 12.1240 13.1246 14.1253 15.1260 16.1264 17.1305 18.1325 19.1345 20.1350 21.1352 22.1354 23.1356 24.1365 25.1402 26.1406 27.1420 28.1426 29.1435 30.1453 31.1460 32.1462 33.1503 34.1523 35.1530 36.1532 37.1534 38.1536 39.1543 40.1563 41.1602 42.1604 43.1620 44.1624 45.1635 46.1640 47.1642 48.1653 49.2013 50.2015 51.2031 52.2035 53.2046 54.2051 55.2053 56.2064 57.2103 58.2105 59.2130 60.2134 61.2136 62.2143 63.2145 64.2150 65.2154 66.2156 67.2163 68.2165 69.2301 70.2305 71.2310 72.2314 73.2316 74.2341 75.2345 76.2350 77.2354 78.2356 79.2361 80.2365 81.2406 82.2413 83.2415 84.2431 85.2435 86.2451 87.2453 88.2460 89.2501 90.2503 91.2510 92.2514 93.2516 94.2530 95.2534 96.2536 97.2541 98.2543 99.2561 100.2563 101.2604 102.2613 103.2615 104.2631 105.2635 106.2640 107.2651 108.2653 109.3015 110.3024 111.3026 112.3042 113.3046 114.3051 115.3062 116.3064 117.3105 118.3125 119.3145 120.3150 121.3152 122.3154 123.3156 124.3165 125.3204 126.3206 127.3215 128.3240 129.3246 130.3251 131.3260 132.3264 133.3402 134.3406 135.3415 136.3420 137.3426 138.3451 139.3460 140.3462 141.3501 142.3510 143.3512 144.3514 145.3516 146.3521 147.3541 148.3561 149.3602 150.3604 151.3615 152.3620 153.3624 154.3640 155.3642 156.3651 157.4013 158.4015 159.4026 160.4031 161.4035 162.4051 163.4053 164.4062 165.4103 166.4105 167.4123 168.4125 169.4130 170.4132 171.4136 172.4150 173.4152 174.4156 175.4163 176.4165 177.4206 178.4213 179.4215 180.4231 181.4235 182.4251 183.4253 184.4260 185.4301 186.4305 187.4310 188.4312 189.4316 190.4321 191.4325 192.4350 193.4352 194.4356 195.4361 196.4365 197.4501 198.4503 199.4510 200.4512 201.4516 202.4521 203.4523 204.4530 205.4532 206.4536 207.4561 208.4563 209.4602 210.4613 211.4615 212.4620 213.4631 214.4635 215.4651 216.4653 217.5013 218.5024 219.5026 220.5031 221.5042 222.5046 223.5062 224.5064 225.5103 226.5123 227.5130 228.5132 229.5134 230.5136 231.5143 232.5163 233.5204 234.5206 235.5213 236.5231 237.5240 238.5246 239.5260 240.5264 241.5301 242.5310 243.5312 244.5314 245.5316 246.5321 247.5341 248.5361 249.5402 250.5406 251.5413 252.5420 253.5426 254.5431 255.5460 256.5462 257.5602 258.5604 259.5613 260.5620 261.5624 262.5631 263.5640 264.5642 265.6013 266.6015 267.6024 268.6031 269.6035 270.6042 271.6051 272.6053 273.6103 274.6105 275.6123 276.6125 277.6130 278.6132 279.6134 280.6143 281.6145 282.6150 283.6152 284.6154 285.6204 286.6213 287.6215 288.6231 289.6235 290.6240 291.6251 292.6253 293.6301 294.6305 295.6310 296.6312 297.6314 298.6321 299.6325 300.6341 301.6345 302.6350 303.6352 304.6354 305.6402 306.6413 307.6415 308.6420 309.6431 310.6435 311.6451 312.6453 313.6501 314.6503 315.6510 316.6512 317.6514 318.6521 319.6523 320.6530 321.6532 322.6534 323.6541 324.6543
【结论】
思路不同的数学解法和程序解法可以相互印证。
END