首页 > 试题广场 >

24点游戏算法

[编程题]24点游戏算法
  • 热度指数:138907 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
给出4个1-10的数字,通过加减乘除运算,得到数字为24就算胜利,除法指实数除法运算,运算符仅允许出现在两个数字之间,本题对数字选取顺序无要求,但每个数字仅允许使用一次,且需考虑括号运算。
此题允许数字重复,如3 3 4 4为合法输入,此输入一共有两个3,但是每个数字只允许使用一次,则运算过程中两个3都被选取并进行对应的计算操作。

输入描述:

读入4个[1,10]的整数,数字允许重复,测试用例保证无异常数字。



输出描述:

对于每组案例,输出一行表示能否得到24点,能输出true,不能输出false

示例1

输入

7 2 1 10

输出

true
while True:
    try:
        l=input().split()
        l=[int(i) for i in l]
        def do(x,y):
            a=x+y
            b=abs(x-y)
            c=x*y
            ln=[a,b,c]
            if y!=0:
                d=x/y
                ln.append(d)
            if x!=0:
                e=y/x
                ln.append(e)
            return ln
        def go(m,n):
            la=[]
            for i in m:
                lx=do(i, n)
                la.extend(lx)
            return la
        def f(a,b):
            lb=[]
            for i in a:
                for j in b:
                    lb.extend(do(i, j))
            return lb
        flag=False
        l1=go(go(do(l[0], l[1]), l[2]),l[3])
        l2=go(go(do(l[0], l[1]), l[3]),l[2])
        l3=go(go(do(l[0], l[2]), l[1]),l[3])
        l4=go(go(do(l[0], l[2]), l[3]),l[1])
        l5=go(go(do(l[0], l[3]), l[1]),l[2])
        l6=go(go(do(l[0], l[3]), l[2]),l[1])
        l7=f(do(l[0], l[1]),do(l[2], l[3]))
        l8=f(do(l[0], l[2]),do(l[1], l[3]))
        l9=f(do(l[0], l[3]),do(l[1], l[2]))
             
        if 24 in (l1+l2+l3+l4+l5+l6+l7+l8+l9):
            flag=True
        if flag:
            print('true')
        else:
            print('false')
    except:
        break

发表于 2021-12-05 19:50:51 回复(0)
本题默认可以交换顺序,不考虑使用括号运算
主要使用全排列计算所有组合,每种组合按顺序加减乘除 
时间复杂度较高
import java.util.*;
public class Main {
    //本题默认可以交换顺序,不考虑使用括号运算
    static Set<Double[]> allSort = new HashSet<>();//存储全排列组合

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            double[] d = new double[4];
            d[0] = sc.nextInt();
            d[1] = sc.nextInt();
            d[2] = sc.nextInt();
            d[3] = sc.nextInt();
            allSort(d, 0);//计算全排列
            
            boolean flag = false;//判断是否有ture
            for (Double[] doubles : allSort) {//遍历set
                if (solve(doubles, doubles[0], 0)) {//
                    flag = true;//出现了成功的情况,跳出循环
                    System.out.println(true);
                    break;
                }
            }
            if(!flag){//没有成功的情况
                System.out.println(false);
            }
            allSort.clear();//set清空
        }
    }

    //计算每一种排列是否可以24点  dfs递归 flag:表示计算到的下标
            //result 初始化为 double数组的第一位 flag初始化为0
    private static boolean solve(Double[] d, double result, int flag) {
        if (flag == 3 && result == 24) {//满足条件的递归出口 
            return true; //计算到了最后一位且 结果恰巧为24
        }
        if(flag == 3 && result != 24){//不满足条件的递归出口 
            return  false;
        }
        flag++;
        return solve(d, result + d[flag], flag) ||
                solve(d, result - d[flag], flag) ||
                solve(d, result * d[flag], flag) ||
                solve(d, result / d[flag], flag);
    }

    //全排列 详情见剑指offer 38 题
    private static void allSort(double[] d, int index) {
        if (index == d.length - 1) {
            allSort.add(new Double[]{d[0], d[1], d[2], d[3]});
            return;
        }

        for (int i = index; i <= d.length - 1; i++) {
            swap(d, index, i);
            allSort(d, index + 1);
            swap(d, index, i);
        }

    }

    //交换
    private static void swap(double[] a, int i, int j) {
        double temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }


}


编辑于 2021-04-06 10:53:23 回复(0)
import sys
def check_24(l):
    for i in l:
        l1 = l.copy()
        l1.remove(i)
        for j in l1:
            l2 = l1.copy()
            l2.remove(j)
            for k in l2:
                l3 = l2.copy()
                l3.remove(k)
                for z in l3:
                    if cal_24(str(i),str(j),str(k),str(z)) == True:
                        return 'true'
    return 'false'
def cal_24(a,b,c,d):
    symbol = ['+','-','*','/']
    for k in range(0,len(symbol)):
        for l in range(0,len(symbol)):
            for n in range(0,len(symbol)):
                if eval('('+'('+a+symbol[k]+b+')'+symbol[l]+c+')'+symbol[n]+d) == 24:
                    return True
    return False

try:
    while True:
        line = sys.stdin.readline().strip()
        if line == '':
            break
        x = list(map(int, line.split()))
        print(check_24(x))
except:
    pass




编辑于 2020-09-11 18:09:23 回复(0)
递归,将多个元素拆成一个加多个,用多个分别与一个加减乘除,看是否能得到最终结果
#include<bits/stdc++.h>
using namespace std;
/*
TRAILBLAZERS
Attack AT DAWN
*/
bool is24(vector<double> a,int dot,double result);
int main(){
    vector<double> a(4,0);
    while(cin>>a[0]>>a[1]>>a[2]>>a[3])
    {
    	if(is24(a,24,0))
        cout<<"true"<<endl;
        else
        {
        	cout<<"false"<<endl;
		}
	}
    return 0;
}
bool is24(vector<double> a,int dot,double result)
{
	if(a.empty())//如果传来的向量已经为空了,那么就判断得到的结果与目标结果
	 {          //是否一致;
	    return dot==result;//如果相等,返回true,如果不等,返回false;  
	 }
	 for(int i=0;i<a.size();i++)//把ABCD分成A(BCD),ACD(B),ABD(C),ABC(D); 
	 {
	 	//再把每种情况分成三个数的结果分别与一个数的加减乘除,看每种情况是否能得到dot
		vector<double> b(a);//用向量a初始化向量b;
		b.erase(b.begin()+i);//表示删除向量中的第i个元素,剩余元素运算 
	 	if(is24(b,dot,result+a[i])||
		 is24(b,dot,result-a[i])||
		 is24(b,dot,result*a[i])||
		 is24(b,dot,result/a[i]))
		 {
		 	return true;
		 }
	 }
	 return false;
}


发表于 2020-06-05 12:30:43 回复(0)
~万物皆可递归~
#include <stdbool.h>
bool s;
void cacuCheck(double num[],bool visited[],int rest){
    if (rest==1) {
        for (int i=0; i<4; i++)
            if (!visited[i])
                if (num[i]==24)
                    s=true;
        return;
    }
    for (int i=0; i<4; i++) {
        if (!visited[i]) {
            for (int j=i+1; j<4; j++) {
                if (!visited[j]) {
                    double a=num[i];
                    double b=num[j];
                    visited[i]=true;
                    visited[j]=true;
                    for (int k=0; k<4; k++) {
                        switch (k) {
                            case 0:
                                num[i]=a+b;
                                visited[i]=false;
                                cacuCheck(num, visited, rest-1);
                                break;
                            case 1:
                                num[i]=a-b;
                                visited[i]=false;
                                cacuCheck(num, visited, rest-1);
                                num[i]=b-a;
                                visited[i]=false;
                                cacuCheck(num, visited, rest-1);
                                break;
                            case 2:
                                num[i]=a*b;
                                visited[i]=false;
                                cacuCheck(num, visited, rest-1);
                                break;
                            case 3:
                                if (a!=0) {
                                    num[i]=b/a;
                                    visited[i]=false;
                                    cacuCheck(num, visited, rest-1);
                                    break;
                                }
                                if (b!=0) {
                                    num[i]=a/b;
                                    visited[i]=false;
                                    cacuCheck(num, visited, rest-1);
                                    break;
                                }
                                break;
                            default:
                                break;
                        }
                    }
                    num[i]=a;
                    num[j]=b;
                    visited[i]=false;
                    visited[j]=false;
                }
            }
        }
    }
}

int main(){
    void cacuCheck(double [],bool [],int );
    double num[4];
    while (~scanf("%lf%lf%lf%lf",&num[0],&num[1],&num[2],&num[3])) {
        bool visited[4]={false};
        s=false;
        //按序从列表选择两数
        for (int i=0; i<4; i++) {
            for (int j=i+1; j<4; j++) {
                double a=num[i];
                double b=num[j];
                visited[i]=true;
                visited[j]=true;
                for (int k=0; k<4; k++) { //两数依次作加减乘除运算,结果重新填入列表中
                    switch (k) {
                        case 0:
                            num[i]=a+b;
                            visited[i]=false;
                            cacuCheck(num, visited, 3);
                            break;
                        case 1:
                            num[i]=a-b;
                            visited[i]=false;
                            cacuCheck(num, visited, 3);
                            num[i]=b-a;
                            visited[i]=false;
                            cacuCheck(num, visited, 3);
                            break;
                        case 2:
                            num[i]=a*b;
                            visited[i]=false;
                            cacuCheck(num, visited, 3);
                            break;
                        case 3:
                            if (a!=0) {
                                num[i]=b/a;
                                visited[i]=false;
                                cacuCheck(num, visited, 3);
                                break;
                            }
                            if (b!=0) {
                                num[i]=a/b;
                                visited[i]=false;
                                cacuCheck(num, visited, 3);
                                break;
                            }
                            break;
                        default:
                            break;
                    }
                }
                num[i]=a;
                num[j]=b;
                visited[i]=false;
                visited[j]=false;
                if (s)
                    break;
            }
            if (s)
                break;
        }
        if (s)
            printf("true\n");
        else
            printf("false\n");
    }
    return 0;
}


发表于 2020-05-18 20:25:24 回复(0)
#include <iostream>
#include <vector>
using namespace std;
bool is24(vector <double> a, int dot, double result)
{
	if (a.empty())return dot == result;
	for (int i = 0; i < a.size(); i++)
	{
		vector<double> b(a);
		b.erase(b.begin() + i);
		if (is24(b, dot, result + a[i]) || \
			is24(b, dot, result - a[i]) || \
			is24(b, dot, result*a[i]) || \
			is24(b, dot, result / a[i]))
			return true;
	}
	return false;
}
int main()
{
	vector<double> a(4,0);
	while (cin >> a[0] >> a[1] >> a[2] >> a[3])
	{
		if (is24(a, 24, 0))
			cout << "true" << endl;
		else
			cout << "false" << endl;	
	}
	return 0;
}

编辑于 2020-04-11 16:24:31 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            double[] num = new double[4];
            for (int i = 0; i < 4; i++) {
                num[i] = scanner.nextDouble();
            }
            boolean flag = false;
            for (int i = 0; i < 4 && !flag; i++) {
                if (num[i] == 0)
                    continue;
                for (int j = i + 1; j < 4 && !flag; j++) {
                    for (int j2 = 0; j2 < 4 && !flag; j2++) {
                        if (j2 == i || j2 == j)
                            continue;
                        for (int k = 0; k < 4 && !flag; k++) {
                            if (k == i || k == j || k == j2)
                                continue;
                            flag = find(num[i], num[j], num[j2], num[k], true);
                        }
                    }
                }
            }
            System.out.println(flag);
        }
        scanner.close();
    }

    public static boolean find(double a, double b, double c, double d, boolean flag) {
        if (b == 0) {
            if (Math.abs(Math.abs(a) - 24) < 0.01)
                return true;
            else
                return false;
        }
        if (find(a + b, c, d, 0, false)) {
            // System.out.println(a + "+" + b + "=" + (double) (a + b));
            return true;
        }
        if (find(a * b, c, d, 0, false)) {
            // System.out.println(a + "*" + b + "=" + (double) (a * b));
            return true;
        }
        if (find(a / b, c, d, 0, false)) {
            // System.out.println(a + "/" + b + "=" + (double) (a / b));
            return true;
        }
        if (find(b / a, c, d, 0, false)) {
            // System.out.println(b + "/" + a + "=" + (double) (b / a));
            return true;
        }
        if (a != b)
            if (find(a - b, c, d, 0, false)) {
                // System.out.println(a + "-" + b + "=" + (double) (a - b));
                return true;
            }
        if (flag) {
            for (int i = 0; i < 5 - (a == b ? 1 : 0); i++) {
                for (int j = 0; j < 5 - (c == d ? 1 : 0); j++) {
                    if (find(calculate(a, b, i), calculate(c, d, j), 0, 0, false)) {
                        // switch (i) {
                        //     case 0:
                        //         System.out.println(a + "+" + b + "=" + (double) (a + b));
                        //         break;
                        //     case 1:
                        //         System.out.println(a + "*" + b + "=" + (double) (a * b));
                        //         break;
                        //     case 2:
                        //         System.out.println(a + "/" + b + "=" + (double) (a/b));
                        //         break;
                        //     case 3:
                        //         System.out.println(b + "/" + a + "=" + (double) (b/a));
                        //         break;
                        //     case 4:
                        //         System.out.println(a + "-" + b + "=" + (double) (a - b));
                        //         break;
                        //     default:
                        //         break;
                        // }
                        // switch (j) {
                        //     case 0:
                        //         System.out.println(c + "+" + d + "=" + (double) (c + d));
                        //         break;
                        //     case 1:
                        //         System.out.println(c + "*" + d + "=" + (double) (c * d));
                        //         break;
                        //     case 2:
                        //         System.out.println(c + "/" + d + "=" + (double) (c/d));
                        //         break;
                        //     case 3:
                        //         System.out.println(d + "/" + c + "=" + (double) (d/c));
                        //         break;
                        //     case 4:
                        //         System.out.println(c + "-" + d + "=" + (double) (c - d));
                        //         break;
                        //     default:
                        //         break;
                        // }
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public static double calculate(double a, double b, int i) {
        switch (i) {
            case 0:
                return a + b;
            case 1:
                return a * b;
            case 2:
                return a / b;
            case 3:
                return b / a;
            case 4:
                return a - b;

            default:
                return 0;
        }
    }
}
ac代码,考虑了所有情况,把注释行去掉是倒序输出计算过程。
发表于 2020-03-09 15:44:40 回复(0)
# 题目的隐藏条件好像是,不考虑使用括号,数字位置可调
def helper(arr, item):
    if item < 1:
        return False
    if len(arr) == 1:
        return arr[0] == item
    for i in range(len(arr)):
        L = arr[:i] + arr[i+1:]
        v = arr[i]
        if helper(L, item-v) or helper(L, item+v) or helper(L, item*v) or helper(L, item/v):
            return True
    return False
while True:
    try:
        arr = list(map(int, input().split(' ')))
        if helper(arr, 24):
            print("true")
        else:
            print("false")
    except:
        break

发表于 2019-08-20 11:15:30 回复(6)
分享一下我的做法。DFS搜索
#include <stdio.h>
#include <algorithm>
using namespace std;
const int N=4;
int num[N];
int isSolve=0;
void dfs(int index,int currentNum,int arr[])
{
        if(currentNum==24)
        {
                isSolve=1;
                return;
        }
        if(isSolve||currentNum>24||index>=4)
                return;
        for(int operFlag=0;operFlag<4;operFlag++)
        {
                switch(operFlag)
                {
                        case 0:
                                dfs(index+1,currentNum+arr[index],arr);
                                break;
                        case 1:
                                dfs(index+1,currentNum-arr[index],arr);
                                break;
                        case 2:
                                dfs(index+1,currentNum*arr[index],arr);
                                break;
                        case 3:
                                dfs(index+1,currentNum/arr[index],arr);
                                break;
                }
                if(isSolve)
                        return;
        }
}
int main()
{
        while(scanf("%d%d%d%d",&num[0],&num[1],&num[2],&num[3])>0)
        {
                isSolve=0;
                sort(num,num+4);
                do
                {
                        dfs(1,num[0],num);
                        if(isSolve)
                                break;
                } while (next_permutation(num,num+4));
                if(isSolve)
                        printf("true\n");
                else
                        printf("false\n");
        }
        return 0;
}


发表于 2016-03-15 22:12:52 回复(29)
#include <iostream>
#include <math.h>
/*思路:采用递归的方式,每次只取两个数做加减乘除运算,并放回数组中,直到数据中只剩下一个数,判断这个数是否等于24*/

#define LING 1E-6


using namespace std;

bool find(double *numR,int n)
{
	double num[4] = {0};
	for(int i=0;i<n;i++)
	{
		num[i] = numR[i];
	}
	
	if(n == 1)
	{
		cout<<num[0]<<endl;              //查看所有运算结果
		if(fabs(num[0]-24) <= LING)
		
			return true;
			
		
		else
			return false;
	}
	for(int i=0;i<n;i++)
		for(int j=i+1;j<n;j++)
		{
			double a,b;
			a = num[i];
			b = num[j];
			num[j] = num[n-1];				//一个偷懒技巧,自个儿画画图就明白了
			num[i] = a+b;
			if(find(num,n-1))
				return true;
			num[i] = a-b;
			if(find(num,n-1))
				return true;
			num[i] = b-a;
			if(find(num,n-1))
				return true;
			num[i] = a*b;
			if(find(num,n-1))
				return true;
			if(b!=0)
			{
				num[i] = a/b;
				if(find(num,n-1))
					return true;
			}
			if(a!=0)
			{
				num[i] = b/a;
				if(find(num,n-1))
					return true;
			}
			num[i] = a;         //一开始我特么没加这两句,不同输入顺序结果不一样???!!!
			num[j] = b;			//这是因为啊,我下次递归的时候要恢复现场啊!!!!!!!!
			
			
		}
		return false;
	

}

int main()
{
	double num[4]= {0};
	while(cin>>num[0]>>num[1]>>num[2]>>num[3])
	{
		bool res = false;
	
	
		res = find(num,4);
		if(res)
			cout<<"true"<<endl;
		else
			cout<<"false"<<endl;
	}
	return 0;
	
}

发表于 2016-06-29 22:05:23 回复(5)
// 暴力穷举
#include<iostream>
#include<vector>
using namespace std;
bool is24(vector<double> a, int tot, double result)
{
    if(a.empty())
    {
        return result==tot;
    }
    for(int i=0; i<a.size() ;i++)
    {
        vector<double> b(a);
        b.erase(b.begin()+i);
        if(is24(b,tot,result+a[i])
           || is24(b,tot,result-a[i])
           || is24(b,tot,result*a[i])
           || is24(b,tot,result/a[i]))
            return true;
    }
    return false;
}
int main()
{
    vector<double> a(4,0);
    while(cin >> a[0] >> a[1] >> a[2] >> a[3])
    {
        if(is24(a,24,0))
            cout<<"true"<<endl;
        else cout<<"false"<<endl;
    }
}
发表于 2018-05-03 10:23:34 回复(12)
import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner input=new Scanner(System.in);
		double result=0.0;
		int[] num=new int[4];
		while(input.hasNext()){
			int[] temp=new int[4];
			for(int i=0;i<4;i++){
				num[i]=input.nextInt();
			}
			System.out.println(check(num,temp,result));
		}
		input.close();
	}

	private static boolean check(int[] num,int[] temp,double result) {
		for(int i=0;i<num.length;i++){
			if(temp[i]==0){
				temp[i]=1;
				if(check(num,temp,result+num[i])
						|| check(num,temp,result-num[i])
						|| check(num,temp,result*num[i])
						|| check(num,temp,result/num[i])){
					return true;
				}
				temp[i]=0;
			}
		}
		if(result==24){
			return true;
		}else{
			return false;
		}
	}
}


发表于 2016-10-13 17:55:42 回复(11)
笨办法:
import itertools
def is24():
    l = ['+', '-', '*', '/']
    for num in itertools.permutations(input().split()):
        a, b, c, d = num
        for i in l:
            for j in l:
                for k in l:
                    fir = eval(str(a) + i + str(b))
                    sec = eval(str(fir)+ j + str(c))
                    if 24 == eval(str(sec)+ k + str(d)):
                        return 'true'
    else:
        return 'false'
while True:
    try:
        print(is24())
    except:
        break


发表于 2020-08-11 15:22:19 回复(6)
#分享一种最蠢的方法,真穷举法
while True:        
    try:
        list1=input().split()
        list6=['+','-','*','/']
        flag=False
        for ii in list1:
            list2=list1.copy()
            list2.remove(ii)
            for jj in list2:
                list3=list2.copy()
                list3.remove(jj)
                for xx in list3:
                    list4=list3.copy()
                    list4.remove(xx)
                    list5=[ii,jj,xx,list4[0]]
                    for i in list6:
                        for j in list6:
                            for x in list6:
                                try:
                                    m0=eval('('+str(list5[0])+i+str(list5[1])+')'+j+str(list5[2])+x+str(list5[3]))
                                except ZeroDivisionError:
                                    m0=0
                                try:
                                    m1=eval(str(list5[0])+i+'('+str(list5[1])+j+str(list5[2])+')'+x+str(list5[3]))
                                except ZeroDivisionError:
                                    m1=0
                                try:
                                    m2=eval(str(list5[0])+i+str(list5[1])+j+'('+str(list5[2])+x+str(list5[3])+')')
                                except ZeroDivisionError:
                                    m2=0 
                                try:
                                    m3=eval('('+str(list5[0])+i+str(list5[1])+')'+j+'('+str(list5[2])+x+str(list5[3])+')')
                                except ZeroDivisionError:
                                    m3=0
                                try:
                                    m4=eval('('+str(list5[0])+i+str(list5[1])+j+str(list5[2])+')'+x+str(list5[3]))
                                except ZeroDivisionError:
                                    m4=0 
                                try:
                                    m5=eval(str(list5[0])+i+'('+str(list5[1])+j+str(list5[2])+x+str(list5[3])+')')
                                except ZeroDivisionError:
                                    m5=0 
                                try:
                                    m6=eval('('+'('+str(list5[0])+i+str(list5[1])+')'+j+str(list5[2])+')'+x+str(list5[3]))
                                except ZeroDivisionError:
                                    m6=0 
                                try:
                                    m7=eval('('+str(list5[0])+i+'('+str(list5[1])+j+str(list5[2])+')'+')'+x+str(list5[3]))
                                except ZeroDivisionError:
                                    m7=0 
                                try:
                                    m8=eval(str(list5[0])+i+'('+'('+str(list5[1])+j+str(list5[2])+')'+x+str(list5[3])+')')
                                except ZeroDivisionError:
                                    m8=0 
                                try:
                                    m9=eval(str(list5[0])+i+'('+str(list5[1])+j+'('+str(list5[2])+x+str(list5[3])+')'+')')
                                except ZeroDivisionError:
                                    m9=0 
                                try:
                                    m10=eval(str(list5[0])+i+str(list5[1])+j+str(list5[2])+x+str(list5[3]))
                                except ZeroDivisionError:
                                    m10=0
                                list7=[m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10]
                                if int(24) in list7:
                                    flag=True
        if flag:
            print('true')
        else:
            print('false')
    except:
        break


编辑于 2019-08-27 15:56:45 回复(6)
//搞了半天原来是可以有括号的,全排列+递归就可以了,而全排列本身又可以递归来做。
//不要忘记恢复现场就行。
#include<iostream>
using namespace std;

inline void Swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

bool is24(int a[], int begin, int end, double tot)
{
	if (begin==end-1) return (a[begin] == tot);
	else
	{
		bool ans = false;
		for (int i = begin; i<end; i++)
		{
			swap(a[i], a[end-1]);
			ans = ans || is24(a, begin, end - 1, tot + a[end - 1]) || is24(a, begin, end - 1, tot - a[end - 1]) || is24(a, begin, end - 1, tot * a[end - 1]) || is24(a, begin, end - 1, tot / a[end - 1]);
			swap(a[i], a[end-1]);
		}
		return ans;
	}


}

int main()
{
	int a[4];
	while (cin >> a[0] >> a[1] >> a[2]>>a[3])
	{
		if (is24(a, 0,4, 24)) cout << "true" << endl;
		else cout << "false" << endl;
	}
}

发表于 2017-07-30 14:10:58 回复(7)
将四个数字分成 A | B C D , A  B |  C D, A  B C | D,每个子部分再递归划分,然后计算所有两部分的可能结果,最终找出结果如果包含24那么有解,此外除法非整除的不能算入结果内,且被除数不能为0.不过这样不能解带分数的情况 8 3 8 3   8/(3-(8/3))。此题也没给这么严格的用例。
#include<stdio.h> #include<vector> #include<algorithm> 
using namespace std;
vector<int> fn24(intnums[],inti,intj)
{
if(i == j)
{
vector<int> ret;
ret.push_back(nums[i]);
returnret;
}
vector<int> result;
for(inti1 = i + 1; i1 <= j; i1++)
{
vector<int> left = fn24(nums,i,i1-1);
vector<int> right = fn24(nums,i1,j);
for(intki = 0; ki < left.size(); ki++)
{
for(intkj = 0; kj < right.size(); kj++)
{
result.push_back(left[ki]+right[kj]);
result.push_back(left[ki]-right[kj]);
result.push_back(left[ki]*right[kj]);
if(right[kj] != 0&& left[ki]%right[kj] == 0)
{
result.push_back(left[ki]/right[kj]);
}
}
}
}
returnresult;
}
intmain()
{
intnums[4];
bool ret;
while(scanf("%d%d%d%d",&nums[0],&nums[1],&nums[2],&nums[3]) != EOF){
ret = false;
sort(nums,nums+4);
do
{
vector<int> result = fn24(nums,0,3);
for(inti = 0; i < result.size(); i++)
{
if(result[i] == 24)
{
ret = true;
break;
}
}
if(ret) break;
} while(next_permutation(nums,nums+4));
printf( ret ? "true\n": "false\n");
}
return0;
}


编辑于 2016-03-27 22:08:32 回复(2)
一个过关90%的快速方法(亲测有效):
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            for (int i = 0; i < 4; i++) {
               scanner.nextInt();
            }
            System.out.println("true");
        }
    }
}


发表于 2021-12-05 18:05:47 回复(6)
def point24(m,n):
  if n < 1:
    return False
  elif len(m) == 1:
      if m[0] == n:
          return True
      else:
          return False
  # 四个数的运算结果等于其中三个数的运算结果与第四个数的运算结果
  for i in range(len(m)):
      a = m[i]
      b = m[:i] + m[i+1:]
      if point24(b,n-a)&nbs***bsp;point24(b,n+a)&nbs***bsp;point24(b,n*a)&nbs***bsp;point24(b,n/a):
        return True
while True:
  try:
      c = list(map(int,input().split()))
      if point24(c,24):
        print("true")
      else:
        print("false")
  except:
      break

发表于 2020-02-21 16:47:51 回复(2)
print('true') #幽默一下,可以通过18组用例
发表于 2024-01-05 15:55:20 回复(2)
1. 关于题解中“好像”没有考虑括号的问题?
所有的括号运算,都等价于把这个括号里的式子放在最开头来算,比如 2*(3+1) 就等价于递归运算中的3+1*2,虽然表面上乘法的优先级比较高,但在实际递归中,是先算了3+1=4,然后把4放在下一个运算中,也就是再算了4*2。  所以题解要求所有的数字全排列,就是为了对所有括号的可能性进行运算。
2. 关于提交时,19/20, 9 9 7 10 一直不通过的问题?
9 9 7 10算出来应该是false,但用上面的思路一直true,测试用例中通过了19个,说明思路是没问题的。 通过一个字符数组,记录了每个答案对应的运算式子,发现9 9 7 10 对应的式子是9+10*9/7 也就是(9+10)*9/7,这整除得不到24,但由于我用了int型,会自动四舍五入成24,这就是true的由来。
发表于 2022-08-01 14:28:55 回复(0)

问题信息

难度:
341条回答 40964浏览

热门推荐

通过挑战的用户

查看代码
24点游戏算法