题解 | #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;
  }
}
全部评论

相关推荐

jack_miller:我给我们导员说我不在这里转正,可能没三方签了。导员说没事学校催的时候帮我想办法应付一下
点赞 评论 收藏
分享
评论
点赞
收藏
分享
正在热议
# 25届秋招总结 #
442240次浏览 4509人参与
# 春招别灰心,我们一人来一句鼓励 #
41913次浏览 531人参与
# 北方华创开奖 #
107422次浏览 599人参与
# 地方国企笔面经互助 #
7961次浏览 18人参与
# 同bg的你秋招战况如何? #
76585次浏览 561人参与
# 虾皮求职进展汇总 #
115499次浏览 886人参与
# 阿里云管培生offer #
120209次浏览 2219人参与
# 实习,投递多份简历没人回复怎么办 #
2454609次浏览 34856人参与
# 实习必须要去大厂吗? #
55761次浏览 961人参与
# 提前批简历挂麻了怎么办 #
149889次浏览 1977人参与
# 投递实习岗位前的准备 #
1195913次浏览 18548人参与
# 你投递的公司有几家约面了? #
33203次浏览 188人参与
# 双非本科求职如何逆袭 #
662189次浏览 7394人参与
# 如果公司给你放一天假,你会怎么度过? #
4751次浏览 55人参与
# 机械人春招想让哪家公司来捞你? #
157622次浏览 2267人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
11535次浏览 284人参与
# 发工资后,你做的第一件事是什么 #
12682次浏览 62人参与
# 工作中,努力重要还是选择重要? #
35793次浏览 384人参与
# 参加完秋招的机械人,还参加春招吗? #
20120次浏览 240人参与
# 我的上岸简历长这样 #
452000次浏览 8088人参与
# 实习想申请秋招offer,能不能argue薪资 #
39289次浏览 314人参与
# 非技术岗是怎么找实习的 #
155866次浏览 2120人参与
牛客网
牛客企业服务