题解 | #24点运算#

24点运算

http://www.nowcoder.com/practice/7e124483271e4c979a82eb2956544f9d

  • 实际上是允许有括号的
  • 先将输入的字母转换成待处理的数字
  • 要通过input得到sum。即:遍历每个input元素(正负不能改变),加减乘除剩下的元素,递归判断能否得到对应的sum加减乘除。注意除的时候,余数必须为0
  • 计算完成后,将处理的数字转换成字母,注意开头的+号是不需要的
import java.util.Scanner;

/**
 * class com.sloera.nowcoder
 * user sloera
 * date 2022/2/27
 */
public class Main {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    // 注意 hasNext 和 hasNextLine 的区别
    while (in.hasNextLine()) { // 注意 while 处理多个 case
      final String s = in.nextLine();
      String result = resolve(s);
      System.out.println(result);
    }
  }

  private static String resolve(String s) {
    // 3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
    if (s.contains("joker") || s.contains("JOKER")) {
      return "ERROR";
    }
    final String[] split = s.split("\\s+");
    int[] input = new int[split.length];
    // 得到输入的数字
    // 2.牌面2~10对应的权值为2~10, J、Q、K、A权值分别为为11、12、13、1;
    for (int i = 0; i < split.length; i++) {
      switch (split[i]) {
        case "J": input[i] = 11; break;
        case "Q": input[i] = 12; break;
        case "K": input[i] = 13; break;
        case "A": input[i] = 1; break;
        default:
          input[i] = Integer.parseInt(split[i]);
      }
    }
    // 计算是否能得到24点
    final char[] operators = new char[4];
    final int[] number = new int[4];
    boolean flag = canculate(operators, number, input, 24);
    if (flag) {
      final StringBuilder stringBuilder = new StringBuilder();
      for (int i = number.length-1; i >= 0; i--) {
        if (i != number.length - 1 || operators[i] != '+') {
          stringBuilder.append(operators[i]);
        }
        if (number[i] == 1) {
          stringBuilder.append('A');
        } else if (number[i] == 11) {
          stringBuilder.append('J');
        }else if (number[i] == 12) {
          stringBuilder.append('Q');
        }else if (number[i] == 13) {
          stringBuilder.append('K');
        } else {
          stringBuilder.append(number[i]);
        }
      }
      return stringBuilder.toString();
    }
    return "NONE";
  }

  /**
   * 是否能由 input 中的数字,计算出sum
   *
   * @param operators 操作符记录
   * @param number 数字计算顺序
   * @param input 可选数字
   * @param sum 总数
   * @return boolean
   * @date 2022/2/27
   */
  private static boolean canculate(char[] operators, int[] number, int[] input, int sum) {
    if (input.length == 1) {
      if (input[0] == sum) {
        operators[3] = '+';
        number[3] = sum;
        return true;
      }
    }
    for (int i = 0; i < input.length; i++) {
      int[] newInput = getNewInput(input, i);
      //  ? = sum + input[i]
      if (canculate(operators, number, newInput, sum + input[i])) {
        // 这里记录的是input[i], ? 已经在递归里面记录了
        operators[operators.length - newInput.length - 1] = '-';
        // 这里记录的是input[i], ? 已经在递归里面记录了
        number[number.length - newInput.length - 1] = input[i];
        return true;
      }
      //  ? = sum - input[i]
      if (canculate(operators, number, newInput, sum - input[i])) {
        // 这里记录的是input[i], ? 已经在递归里面记录了
        operators[operators.length - newInput.length - 1] = '+';
        // 这里记录的是input[i], ? 已经在递归里面记录了
        number[number.length - newInput.length - 1] = input[i];
        return true;
      }
      //  ? = sum * input[i]
      if (canculate(operators, number, newInput, sum * input[i])) {
        // 这里记录的是input[i], ? 已经在递归里面记录了
        operators[operators.length - newInput.length - 1] = '/';
        // 这里记录的是input[i], ? 已经在递归里面记录了
        number[number.length - newInput.length - 1] = input[i];
        return true;
      }
      //  ? = sum / input[i]
      if (canculate(operators, number, newInput, sum / input[i])  && (sum % input[i] == 0)) {
        // 这里记录的是input[i], ? 已经在递归里面记录了
        operators[operators.length - newInput.length - 1] = '*';
        // 这里记录的是input[i], ? 已经在递归里面记录了
        number[number.length - newInput.length - 1] = input[i];
        return true;
      }
    }
    return false;
  }

  /**
   * 获取input中,除index索引所在位置的新数组
   *
   * @param input 原始数组
   * @param index 待去除索引
   * @return int[]
   * @date 2022/2/27
   */
  private static int[] getNewInput(int[] input, int index) {
    final int[] ints = new int[input.length - 1];
    int j = 0;
    for (int i = 0; i < input.length; i++) {
      if (i != index) {
        ints[j++] = input[i];
      }
    }
    return ints;
  }
}
全部评论

相关推荐

11-26 22:34
已编辑
重庆邮电大学 Java
快手 客户端开发 (n+5)k*16 公积金12
牛客895077908号:佬 什么双非硕啊
点赞 评论 收藏
分享
10-16 22:56
门头沟学院 C++
1234567800:歌尔今年给211开14-15k吗,我本地人连面试都不给😂
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务