题解 | #24点运算#
24点运算
https://www.nowcoder.com/practice/7e124483271e4c979a82eb2956544f9d
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringBuffer bu = new StringBuffer(); String a; String err = "ERROR\n";//错误信息 String none = "NONE\n";//找不到匹配24的信息 try { a = in.readLine(); } catch (IOException e) { throw new RuntimeException(e); } char[] charAy = a.toCharArray(); char[] cards = new char[4]; char[] express = new char[8];//存放算式结果的数组 char n = 0; int i = 0, j = 0, l = charAy.length; boolean joker = false; while (i < l) {//从输入解析出牌字符数组 if (charAy[i] == ' ') { if (n == 'r' || n == 'R') joker = true;//如果输入中含r字符,则表示有joker cards[j++] = n; n = 0; } else { n = charAy[i]; } if (i == l - 1) cards[j] = n; i++; } if (joker) bu.append(err);//有joker输出错误信息 else { if (operate(cards, express)) {//能够找到输出算式 bu.append(getString(express)); } else bu.append(none); } System.out.print(bu); } public static boolean operate(char[] cards, char[] express) { int i = 0, j = 0, l = cards.length; boolean canOperate = false; int[] mark = new int[l]; while (i < l) { mark[i] = 1;//该索引位的牌已被计算 express[j] = cards[i]; if (calculate(mark, cards, express, j + 1, 1, getChrValue(cards[i]))) { canOperate = true; break; } mark[i] = 0;//不满足,重新置为0,进入下次计算过程 i++; } return canOperate; } /** * 计算递归方法 * @param mark 标记是否已经计算 * @param cards 所有的牌 * @param express 计算式数组 * @param j 计算式索引下标 * @param cnt 已用的牌数,等于4表示所有牌都被计算过,进行24判断 * @param res 计算的结果值 * @return 返回是否能计算得出24 */ public static boolean calculate(int[] mark, char[] cards, char[] express, int j, int cnt, int res) { boolean canCal = false; int i = 0, l = mark.length, tmp; if (cnt == 4) { canCal = res == 24; } else { while (i < l) { if (mark[i] == 0) { mark[i] = 1; tmp = getChrValue(cards[i]); express[j] = '+';//数组中该位 置为+ express[j + 1] = cards[i]; canCal = calculate(mark, cards, express, j + 2, cnt + 1, res + tmp); if (canCal) break; express[j] = '-';//数组中该位重置为- canCal = calculate(mark, cards, express, j + 2, cnt + 1, res - tmp); if (canCal) break; express[j] = '*';//数组中该位重置为* canCal = calculate(mark, cards, express, j + 2, cnt + 1, res * tmp); if (canCal) break; express[j] = '/';//数组中该位重置为/ if (res % tmp == 0) canCal = calculate(mark, cards, express, j + 2, cnt + 1, res / tmp); if (canCal) break; mark[i] = 0;//注意回溯 } i++; } } return canCal; } /** * 由字符获得具体的数字,便于计算 * @param chr * @return */ public static int getChrValue(char chr) { int val; if (chr == '0') val = 10; else if (chr == 'J') val = 11; else if (chr == 'Q') val = 12; else if (chr == 'K') val = 13; else if (chr == 'A') val = 1; else val = chr - '0'; return val; } /** * 将数组拼接为算式 * @param chr * @return */ public static StringBuffer getString(char[] chr) { StringBuffer s = new StringBuffer(); int i = 0, l = chr.length; while (i < l) { if (chr[i] == '0') {//0字符表示的数字为10 s.append("10"); i++; continue; } if (chr[i] != ' ') s.append(chr[i]); i++; } return s; } }