首页 > 试题广场 >

24点运算

[编程题]24点运算
  • 热度指数:93487 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

计算24点是一种扑克牌益智游戏,随机抽出4张扑克牌,通过加(+),减(-),乘(*), (/)四种运算法则计算得到整数24,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写joker表示小王,大写JOKER表示大王:

3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER

本程序要求实现:输入4张牌,输出一个算式,算式的结果为24点。

详细说明:

1.运算只考虑加减乘除运算,没有阶乘等特殊运算符号,没有括号,友情提醒,整数除法要当心,是属于整除,比如2/3=0,3/2=1
2.牌面2~10对应的权值为2~10, JQKA权值分别为为1112131
3.输入4张牌为字符串形式,以一个空格隔开,首尾无空格;如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
4.输出的算式格式为4张牌通过+-*/四个运算符相连,中间无空格4张牌出现顺序任意,只要结果正确;
5.输出算式的运算顺序从左至右,不包含括号,如1+2+3*4的结果为24,2 A 9 A不能变为(2+1)*(9-1)=24
6.如果存在多种算式都能计算得出24,只需输出一种即可,如果无法得出24,则输出“NONE”表示无解。
7.因为都是扑克牌,不存在单个牌为0的情况,且没有括号运算,除数(即分母)的数字不可能为0

数据范围:一行由4张牌组成的字符串

输入描述:

输入4张牌为字符串形式,以一个空格隔开,首尾无空格;



输出描述:
输出怎么运算得到24,如果无法得出24,则输出“NONE”表示无解,如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算;
示例1

输入

A A A A

输出

NONE

说明

不能实现           
示例2

输入

4 2 K A

输出

K-A*4/2

说明

 A+K*2-4也是一种答案,输出任意一种即可           
示例3

输入

A 5 joker 4

输出

ERROR

说明

 存在joker,输出ERROR          
示例4

输入

K Q 6 K

输出

NONE

说明

按一般的计算规则来看,K+K-(Q/6)=24 或 K-((Q/6)-K)=24,但是因为这个题目的运算不许有括号,所以去掉括号后变为 K+K-Q/6=26-Q/6=14/6=2 或 K-Q/6-K=1/6-K=0-K=-13,其它情况也不能运算出24点,故不存在,输出NONE   
求助!!!实例 4 2 K A
答案是 K-A*4/2
我写的是K/2*4*A 答案也是24但是就是不算过

import itertools
import sys
from itertools import permutations

# 只考虑 + - * /
# 整数运算 2/3 -> 0 3/2 -> 1
# joker 小王 JOKER 大王 -> ERROR
# J 11 Q 12 K 13 A 1

poker = input().split()
err = ['JOKER', 'joker']
f = ['+', '-', '*', '//']
num = {'J':'11', 'Q':'12', 'K':'13', 'A':'1'}
reverse_num = {v: k for k, v in num.items()} 

# 是否有大小王
def if_err(poker):
    for n in poker:
        if n in err:        
            print('ERROR')
            return False
    return True

# 转换jqka的值
def jqka_num(poker):
    for i in range(len(poker)):
        if poker[i] in num:
            poker[i] = num[poker[i]]
    return poker

# 换回jqka的值
def num_jqka(poker):
    for i in range(len(poker)):
        if poker[i].values in num.values:
            poker[i] = num[poker[i]].values
    return poker


def calcu(poker, target):
    for card in itertools.permutations(poker):
        for func in itertools.product(f, repeat=3):
            my_function = f"(({card[0]}{func[0]}{card[1]}){func[1]}{card[2]}){func[2]}{card[3]}"

            if eval(my_function) == target:
                return ''.join(f"{card[0]}{func[0]}{card[1]}{func[1]}{card[2]}{func[2]}{card[3]}")

    return 'NONE'
    

# main
if if_err(poker) == True:
    poker = jqka_num(poker)
    #poker = list(''.join(num[card] for card in poker)) 
    new_poker = calcu(poker, target = 24)

    for number, letter in reverse_num.items():
        new_poker = new_poker.replace(number, letter)
	
    new_poker = new_poker.replace('//', '/')
    print(new_poker)


发表于 2025-01-14 20:52:41 回复(0)
# 将扑克牌字符转换为对应的值   print_res里面其实已经找出来全部方法
def card_value(card):
    values = {'A': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 
              'J': 11, 'Q': 12, 'K': 13}
    if card in values:
        return values[card]
    return None

def find_24(hardcard,value_path,res):     # 采用dfs
    # print(value_path)
    if not hardcard:
        value, path = value_path
        if value == 24:
            res.append(path)
            # value_path.pop()
        return
    if value_path == []:
        card = hardcard[0]
        value_path= [card_value(card),[card]]
        find_24(hardcard[1:],value_path,res)
    else:
        card = hardcard[0]
        find_24(hardcard[1:],[value_path[0]*card_value(card),value_path[1]+["*"]+[card]],res)
        find_24(hardcard[1:],[value_path[0]-card_value(card),value_path[1]+["-"]+[card]],res)
        find_24(hardcard[1:],[value_path[0]+card_value(card),value_path[1]+["+"]+[card]],res)
        if card_value(card) != 0:
            find_24(hardcard[1:],[value_path[0]//card_value(card),value_path[1]+["/"]+[card]],res)
        # value_path.pop()


from itertools import permutations
hardcards = input().strip().split()
hardcards = permutations(hardcards)
print_res = []
for hardcard in hardcards:
    # print(hardcard)
    record = []
    res = []
    if "joker" in hardcard&nbs***bsp;"JOKER" in hardcard:
        print_res.append(["ERROR"])
        break
    else:
        find_24(hardcard,res,record)
        if not record:
            # print_res.append(["NONE"])
            pass
        else:
            for p in record:
                print_res.append(p)
                # break
# print(*print_res[-1],sep="")
if ["ERROR"] in print_res:
    print("ERROR")
elif print_res==[]:
    print("NONE")
else:
    print(*print_res[0],sep="")

发表于 2024-09-25 16:46:55 回复(0)
熟用内置库捏
import sys
import itertools

calcs_lib = ["+", "-", "*", "/"]
point = {
    "A": 1,
    "2": 2,
    "3": 3,
    "4": 4,
    "5": 5,
    "6": 6,
    "7": 7,
    "8": 8,
    "9": 9,
    "10": 10,
    "J": 11,
    "Q": 12,
    "K": 13,
}
rev_point = {v: k for (k, v) in point.items()}
do_calc = {
    "+": lambda x, y: x + y,
    "-": lambda x, y: x - y,
    "*": lambda x, y: x * y,
    "/": lambda x, y: int(x / y)
}

for line in sys.stdin:
    in_cards = line.split()
if "joker" in in_cards&nbs***bsp;"JOKER" in in_cards:
    print("ERROR")
else:
    card_orders = itertools.permutations([point[i] for i in in_cards], 4)
    for cards in card_orders:
        calc_orders = itertools.product(calcs_lib, calcs_lib, calcs_lib)
        for calcs in calc_orders:
            x = cards[0]
            for card, calc in zip(cards[1:], calcs):
                x = do_calc[calc](x, card)
            if x == 24:
                r = rev_point[cards[0]]
                for card, calc in zip(cards[1:], calcs):
                    r += calc + rev_point[card]
                print(r)
                exit()
    print("NONE")

发表于 2024-09-17 23:12:42 回复(0)
from itertools import permutations
reflect = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, 
            '9':9, '10':10, 'J':11, 'Q':12, 'K':13, 'A':1}
record = []
def func(group, cur, sig):
    if cur == 3:
        res = reflect[group[0]]
        exp = f'{res}'
        for j in range(3):
            new_num = reflect[group[j+1]]
            new_sig = sig[j]
            exp += new_sig + str(new_num)
            res = eval(f'{res}{new_sig}{new_num}')
        if res == 24:
            exp = exp.replace('11', 'J')
            exp = exp.replace('12', 'Q')
            exp = exp.replace('13', 'K')
            exp = exp.replace('1', 'A')
            record.append(exp)
        return
    func(group, cur+1, sig+['+'])
    func(group, cur+1, sig+['-'])
    func(group, cur+1, sig+['*'])
    func(group, cur+1, sig+['/'])    

while True:
    try:
        cards = input().split(' ')
        if 'joker' in cards&nbs***bsp;'JOKER' in cards:
            print('ERROR')
        elif len(set(cards)) == 1:
            if '6' in cards:
                print('+'.join(cards))
            elif 'Q' in cards:
                print('Q+Q+Q-Q')
            elif '4' in cards:
                print('4*4+4+4')
            else:
                print('NONE')
        else:
            p = list(permutations(cards, 4))
            for i in p:
                func(i, 0, [])
            if record:
                print(record[0])
            else:
                print('NONE')
    except:
        break


发表于 2024-08-05 11:02:14 回复(0)
简单般的24点运算问题,题目的要求从前往后计算,不考虑运算优先级以及不考虑加括号运算,该两条运算规则极大降低了24点运算问题的难度,不用递归回溯考虑了。
只需要生成输入扑克牌序列的全排列,使用四个运算符穷举插入,从前往后两两运算即可
import itertools

# 定义牌面和对应的点数
card_points = {
    "3": 3,
    "4": 4,
    "5": 5,
    "6": 6,
    "7": 7,
    "8": 8,
    "9": 9,
    "10": 10,
    "J": 11,
    "Q": 12,
    "K": 13,
    "A": 1,
    "2": 2,
}

# 定义允许的操作符
operators = ["+", "-", "*", "/"]


# 检查输入是否合法
def validate_cards(cards):
    return len(cards) == 4 and all(card in card_points for card in cards)


# 将牌面转换为对应的点数
def get_card_values(cards):
    return [card_points[card] for card in cards]


# 从左到右计算表达式的结果
def evaluate_expression(values, ops):
    result = values[0]
    for i in range(3):
        if ops[i] == "+":
            result += values[i + 1]
        elif ops[i] == "-":
            result -= values[i + 1]
        elif ops[i] == "*":
            result *= values[i + 1]
        elif ops[i] == "/":
            # 避免除以零
            if values[i + 1] == 0:
                return None
            result //= values[i + 1]  # 注意题目要求除号遵循取模运算
    return result


# 尝试所有牌的排列和操作符的组合
def find_expression_for_24(cards):
    for perm in itertools.permutations(cards):
        values = get_card_values(list(perm))
        for ops in itertools.product(operators, repeat=3):
            result = evaluate_expression(values, ops)
            if result == 24:
                # 生成运算式
                expression = (
                    f"{perm[0]}{ops[0]}{perm[1]}{ops[1]}{perm[2]}{ops[2]}{perm[3]}"
                )
                return expression
    return None


# 主函数
def main():
    # 输入四张牌
    cards = input().split()

    # 验证输入是否合法
    if not validate_cards(cards):
        print("ERROR")
        return

    # 尝试找到结果为24的运算式
    expression = find_expression_for_24(cards)

    if expression:
        print(expression)
    else:
        print("NONE")


# 运行主函数
if __name__ == "__main__":
    main()


发表于 2024-05-04 23:49:21 回复(0)
笨方法,但是好理解。
1、找出所有扑克牌的组合
2、找出所有运算符的组合
3、计算是否符合24
POKERR_TABLE = {"3":3, "4":4, "5":5, "6":6, "7":7, "8":8 ,"9":9, "10":10, "J":11, "Q":12, "K":13 ,"A":1, "2": 2}

def compute_nums(one: int, two: int, compute: str)->int:
    if compute == "+":
        return one + two
    if compute == "-":
        return one - two
    if compute == "/":
        return one // two
    if compute == "*":
        return one * two

def answer(pokers:list):
    if "joker" in pokers&nbs***bsp;"JOKER" in pokers:
        return "ERROR"

    digist_compose = set()
    for i, x in enumerate(pokers):
        three_pokers = pokers[0:i] + pokers[i+1:]
        for j, y in enumerate(three_pokers):
            digist_compose.add((x, y, three_pokers[(j+1)%3], three_pokers[(j+2)%3]))
            digist_compose.add((x, y, three_pokers[(j+2)%3], three_pokers[(j+1)%3]))

    computes = ["+", "-", "*", "/"]
    computes_compose = set()
    for x in computes:
        for y in computes:
            for z in  computes:
                computes_compose.add((x, y, z))


    for d in digist_compose:
        one, two, three, four = POKERR_TABLE[d[0]], POKERR_TABLE[d[1]], POKERR_TABLE[d[2]], POKERR_TABLE[d[3]]
        for c in computes_compose:
            one_c, two_c, three_c = c[0], c[1], c[2]
            if compute_nums(compute_nums(compute_nums(one, two, one_c), three, two_c), four, three_c) == 24:
                #print("{}{}{}{}{}{}{}".format(one, one_c, two, two_c, three, three_c, four))
                return "{}{}{}{}{}{}{}".format(d[0], one_c, d[1], two_c, d[2], three_c, d[3])
    return "NONE"
pokers = input().split(" ")
print(answer(pokers))


发表于 2024-01-13 15:28:44 回复(0)
对字符进行组合后使用eval计算,好理解
import itertools
dicts = {'A':'1','J':'11','Q':'12','K':'13','joker':'ERROR','JOKER':'ERROR'}
_dicts = {'1':'A','11':'J','12':'Q','13':'K'}
s = input().split(' ')
method =['+','-','*','/']
values = [dicts[v] if v in dicts else v for v in s]
def getValueFromKey(key):
    return _dicts[key] if key in _dicts else key
def jisuan(values):
    a,b,c,d = values[0],values[1],values[2],values[3]
    for i in method:
        for j in method:
            for k in method:
                p = eval(f'{a}{i}{b}')
                p = eval(f'{p}{j}{c}')
                p = eval(f'{p}{k}{d}')
                if eval(f'{p}') == 24:
                    return getValueFromKey(a)+i+getValueFromKey(b)+j+getValueFromKey(c)+k+getValueFromKey(d)
    return None
def choose(values:list):
    permutations = list(itertools.permutations(values))#用itertools感觉简洁很多,我一开始自己写的也能跑,但是套了四层循环像坨屎
    for p in permutations:
        reslut= jisuan(p)
        if reslut:return reslut
    return None
if 'ERROR' in values:print('ERROR')
else:
    reslut = choose(values)
    if reslut:
        print(reslut)
    else:
        print('NONE')



发表于 2023-11-09 20:21:19 回复(0)
from itertools import product,permutations
l = ["0","A","2","3","4","5","6","7","8","9","10","J","Q","K","joker","JOKER"]
s=input().split()
if "joker" in s&nbs***bsp;"JOKER" in s:
    print("ERROR")
else:
    s=[l.index(i) for i in s]
    for i in permutations(s,4):
        for j in product("+-*/",repeat = 3):
            if eval(f"(({i[0]}{j[0]}{i[1]}){j[1]}{i[2]}){j[2]}{i[3]}")==24:
                print(f"{l[i[0]]}{j[0]}{l[i[1]]}{j[1]}{l[i[2]]}{j[2]}{l[i[3]]}")
                exit()
    else:
        print("NONE")

发表于 2023-05-31 14:00:47 回复(1)
#非原创,参考其它大神,我自己梳理了一下思路
from itertools import permutations
pai_li = ["", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
ysf_li = ["+", "-", "*", "/"]
def qiu_24(li: tuple):
    # n 代表没张表的点数
    n1, n2, n3, n4 = [pai_li.index(i) for i in li]
    # f 代表运算符, 4位数加减法,遍历3个运算符即可
    for f1 in ysf_li:
        for f2 in ysf_li:
            for f3 in ysf_li:
                # 构造一个算式 ( (n1 [+-*/] n2) [+-*/] n3) [+-*/] n4
                # [+-*/] 任意1个
                s = f"( ({n1} {f1} {n2}) {f2} {n3}) {f3} {n4}"
                if eval(s) == 24:
                    return li[0] + f1 + li[1] + f2 + li[2] + f3 + li[3]
    else:
        return False
while True:
    try:
        us_li = input().split()
        if "joker" in us_li or "JOKER" in us_li:
            print("ERROR")
            continue

        #4 张表组合笛卡尔积
        ls_gen = permutations(us_li)
        for li in ls_gen:
            s = qiu_24(li)
            if s:
                print(s)
                break
        else:
            print("NONE")
    except:
        break
发表于 2023-05-18 23:24:10 回复(0)
import itertools

symbol = ["+", "-", "*", "//"]
dic = {"J": "11", "Q": "12", "K": "13", "A": "1"}
dic_ = {"11": "J", "12": "Q", "13": "K", "1": "A", "//":"/"}


def transfer(x):
    for i in range(len(x)):
        if x[i] in dic_.keys():
            x[i] = dic_[x[i]]
    a, i, b, j, c, k, d = x
    return a + i + b + j + c + k + d


def solution(a, b, c, d):
    for nums in itertools.permutations([a, b, c, d]):
        a, b, c, d = nums
        for i in symbol:
            for j in symbol:
                for k in symbol:
                    try:
                        if (
                            eval("(" + "(" + a + i + b + ")" + j + c + ")" + k + d)
                            == 24
                        ):
                            # print([a, i, b, j, c, k, d])
                            return transfer([a, i, b, j, c, k, d])
                    except ZeroDivisionError:
                        continue
    return "NONE"


s = input().strip().split()
for i in range(len(s)):
    if s[i] in dic.keys():
        s[i] = dic[s[i]]

if "joker" in s&nbs***bsp;"JOKER" in s:
    print("ERROR")
else:
    a, b, c, d = s
    print(solution(a, b, c, d))

发表于 2023-04-03 15:41:21 回复(0)
通过给定一个数,计算该数据与预期值的+-*/后的期望值,逐步分解至2个数的计算
发表于 2023-02-24 18:45:23 回复(1)
def permutation(s):
    path = []
    res = []
    def dfs():
        if len(path) == 4:
            res.append(path[:])
            return
        for i in range(4):
            if s[i] != None:
                cur = s[i]
                path.append(cur)
                s[i] = None
                dfs()
                path.pop()
                s[i] = cur
    dfs()
    res = set([''.join(i) for i in res])
    return res

def calculate(s):
    oper = '+-*/'
    for n in s:
        for i in oper:
            for j in oper:
                for t in oper:
                    fun = '(''('+dic[n[0]]+i+dic[n[1]]+')'+j+dic[n[2]]+')'+t+dic[n[3]]
                    if eval(fun) == 24:
                        return n[0]+i+n[1]+j+n[2]+t+n[3]
    return 'NONE'

key = ['A','2','3','4','5','6','7','8','9','10','J','Q','K']
val = ['1','2','3','4','5','6','7','8','9','10','11','12','13']
dic = dict(zip(key, val))

s = input().split()

if 'joker' in s&nbs***bsp;'JOKER' in s:
    print('ERROR')
else:
    s = permutation(s)
    print(calculate(s))
# 暴力枚举法,求四个数的所有组合,然后尝试所有计算组合,一旦等于24就return算式
发表于 2022-11-24 19:45:00 回复(0)
看我题解,这题倒序回溯就好了,简单得一批,,
发表于 2022-07-23 22:21:11 回复(0)
import itertools
Value = {'A':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'J':11, 'Q':12, 'K':13}
Calc = ['+', '-', '*', '//']
s = input()
if 'joker' in s&nbs***bsp;'JOKER' in s:
    print('ERROR')
else:
    a, b, c, d = s.split()
    l = [Value[a], Value[b], Value[c], Value[d]]
    ll = list(itertools.permutations(l))
    s = ''
    for n in ll:
        if s:
            break
        for c1 in Calc:
            if s:
                break
            for c2 in Calc:
                if s:
                    break
                for c3 in Calc:
                    s1 = '((' + str(n[0]) + c1 + str(n[1]) + ')' + c2 + str(n[2]) + ')' + c3 + str(n[3])
                    r = eval(s1)
                    if r == 24:
                        s = str(n[0]) + c1 + str(n[1]) + c2 + str(n[2]) + c3 + str(n[3])
                        break
    if s:
        s = s.replace('//', '/').replace('11', 'J').replace('12', 'Q').replace('13', 'K').replace('1', 'A')
        print(s)
    else:
        print('NONE')

发表于 2021-09-27 23:16:18 回复(0)