蓝桥杯题解-凑算式(全排列变体)

来源:互联网 发布:未来清单软件多少钱 编辑:程序博客网 时间:2024/05/17 09:12

题目

这是蓝桥杯2016年第七届省赛B组合C组都有的一个结果填空题:

凑算式     B      DEFA + --- + ------- = 10     C      GHI(如果显示有问题,可以参见【图1.jpg】)这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。比如:6+8/3+952/714 就是一种解法,5+3/1+972/486 是另一种解法。这个算式一共有多少种解法?注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。

这里写图片描述

分析

因为这是一个结果填空,所以不用过于考虑性能,可以直接用暴力递归求全排列然后验证的方式来完成,9个数字的全排列是9!=362880,是肯定能在秒内完成的。

因此只需在算法思维(递归)训练:输出字符串字符的全排列的基础上稍加修改就行了。

代码

/** * 凑算式 * A+B/C+DEF/GHI=10,A~I可以是1~9的任意不同数字 * * 暴力求解实际就是1~9的全排列,然后验证某一种排列是否能凑成算式 * */public class 凑算式 {  static int res;  public static void main(String[] args) {    String s = "123456789";    // 全排列    permutation(s.toCharArray(), 0);    System.out.println(res);  }  //每一段全排列,都是将每个字符换到前面,求后面段的全排列  //index代表0~index-1都已确认排列,[index,n-1]待排列  private static void permutation(char[] arr, int index) {    //至于什么时候输出,要考虑清楚    if (index == arr.length) {      // 算式凑成功了,打印并计数      if (Double.parseDouble(arr[0] + "") +          Double.parseDouble(arr[1] + "") / Double.parseDouble(arr[2] + "") +          (Double.parseDouble(arr[3] + "") * 100 + Double.parseDouble(arr[4] + "") * 10 + Double.parseDouble(arr[5] + "")) /              (Double.parseDouble(arr[6] + "") * 100 + Double.parseDouble(arr[7] + "") * 10 + Double.parseDouble((arr[8] + ""))) == 10.0) {        // System.out.println(String.valueOf(arr));        res++;      }    }    //现在index之前的字符都已就位,把之后的每个字符都交换到index这个位置    for (int k = index; k < arr.length; k++) {      //尝试交换      swap(arr, index, k);      //交换之后index这个位置就定好了,接下来的事就是递归去解决index+1位置开始的全排列就好了      permutation(arr, index + 1);      // 前面我们尝试交换,把全排列求出来了,交换时只尝试了一个字符,因此for循环继续之前要换回来,继续尝试交换下一个字符      swap(arr, index, k);    }  }  private static void swap(char[] arr, int index, int k) {    char tmp = arr[k];    arr[k] = arr[index];    arr[index] = tmp;  }}

陷阱

注意此题验算算式时,必须用double,因为题目中说6+8/3+952/714是正确的算式,但是直接System.out.println(6+8/3+952/714);输出的是9,这说明全部做整数运算是不对的。

再来验证System.out.println(6+8.0/3+952.0/714);结果是10.0,这说明我们需要在除法运算中使用浮点数。

成功避开此坑才能得到正确答案。

原创粉丝点击