题解 | #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;
    }
}

全部评论

相关推荐

東大沒有派對:这是好事啊(峰哥脸
我的秋招日记
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务