首页 > 试题广场 >

24点运算

[编程题]24点运算
  • 热度指数:87714 时间限制: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

输入

B 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   
#include <stdio.h>
#include <string.h>

char cards[14] = {"A23456789XJQK"};
char str[50];
int value[4];
int number[4];
int sign[3];

int length;

//字符串输入,去换行
void inputer() {
    fgets(str, 50, stdin);
    length = strlen(str);
    if (str[length - 1] == '\n') {
        length--;
        str[length] = 0;
    }
}

//检查字符串有无joker,没有则按权值返回数组
int inputcheck() {
    int idx = 0;
    for (int i = 0; i < length; i++) {
        if ((str[i] == 'j' && str[i + 1] == 'o') || (str[i] == 'J' &&
                str[i + 1] == 'O')) {
            return 0;
        } else if (str[i] != ' ') {
            if (str[i] == '1' && str[i + 1] == '0') {
                value[idx] = 10;
                idx++;
                i++;
            } else {
                switch (str[i]) {
                    case '3':
                        value[idx] = 3;
                        break;
                    case '4':
                        value[idx] = 4;
                        break;
                    case '5':
                        value[idx] = 5;
                        break;
                    case '6':
                        value[idx] = 6;
                        break;
                    case '7':
                        value[idx] = 7;
                        break;
                    case '8':
                        value[idx] = 8;
                        break;
                    case '9':
                        value[idx] = 9;
                        break;
                    case 'J':
                        value[idx] = 11;
                        break;
                    case 'Q':
                        value[idx] = 12;
                        break;
                    case 'K':
                        value[idx] = 13;
                        break;
                    case 'A':
                        value[idx] = 1;
                        break;
                    case '2':
                        value[idx] = 2;
                        break;
                }
                idx++;
            }
        }
    }


    return 1;
}

int calc() {
    int x[3];
    switch (sign[0]) {
        case 0:
            x[0] = number[0] + number[1];
            break;
        case 1:
            x[0] = number[0] - number[1];
            break;
        case 2:
            x[0] = number[0] * number[1];
            break;
        case 3:
            x[0] = number[0] / number[1];
            break;
    }
    switch (sign[1]) {
        case 0:
            x[1] = x[0] + number[2];
            break;
        case 1:
            x[1] = x[0] - number[2];
            break;
        case 2:
            x[1] = x[0] * number[2];
            break;
        case 3:
            x[1] = x[0] / number[2];
            break;
    }
    switch (sign[2]) {
        case 0:
            x[2] = x[1] + number[3];
            break;
        case 1:
            x[2] = x[1] - number[3];
            break;
        case 2:
            x[2] = x[1] * number[3];
            break;
        case 3:
            x[2] = x[1] / number[3];
            break;
    }
    if (x[2] == 24)
        return 1;
    else
        return 0;
}

int calculate() {
    for (int i1 = 0; i1 < 4; i1++) {
        for (int i2 = 0; i2 < 3; i2++) {
            for (int i3 = 0; i3 < 2; i3++) {
                for (int i4 = 0; i4 < 4; i4++) {
                    number[i4] = value[i4];
                }
                //遍历所有顺序
                int a = number[3];
                number[3] = number[i1];
                number[i1] = a;
                a = number[2];
                number[2] = number[i2];
                number[i2] = a;
                a = number[1];
                number[1] = number[i3];
                number[i3] = a;

                //遍历所有符号组合并计算
                for (int j1 = 0; j1 < 4; j1++) {
                    sign[0] = j1;
                    for (int j2 = 0; j2 < 4; j2++) {
                        sign[1] = j2;
                        for (int j3 = 0; j3 < 4; j3++) {
                            sign[2] = j3;
                            if (calc()) {
                                return 1;
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
}

void ptfsign(int n) {
    switch (n) {
        case 0:
            printf("+");
            break;
        case 1:
            printf("-");
            break;
        case 2:
            printf("*");
            break;
        case 3:
            printf("/");
            break;
    }
}

void ptfnumber(int n) {
    if(n==10){
        printf("10");
    }else {
        printf("%c",cards[n-1]);
    }
}

int main() {
    inputer();//输入字符串
    if (inputcheck()) {//检查有没有大小王,将字符串转化为整数
        if (calculate()) {//穷举计算是否有24点组合
            ptfnumber(number[0]);//有则输出
            ptfsign(sign[0]);
            ptfnumber(number[1]);
            ptfsign(sign[1]);
            ptfnumber(number[2]);
            ptfsign(sign[2]);
            ptfnumber(number[3]);
        } else {
            printf("NONE");//没有则NONE
        }
    } else {
        printf("ERROR");//有joker则ERROR
    }


    return 0;
}

发表于 2023-12-08 01:38:02 回复(0)
华为题库HJ89 24点运算
思路:DFS暴力枚举(C语言)
运行时间:3ms,内存:368KB
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int visit[4]={0},result_index=0,order_index=0;
int result[4]={0};
char order[4]={0};
int dfs(int a[],int sum){
    if(sum==24&&order_index==3){
        return 1;
    }else{
        for(int i=0;i<4;i++){
            if(!visit[i]){
                visit[i]=1;
                int flag;
                result[result_index++]=a[i];
                order[order_index++]='+';
                if(dfs(a,sum+a[i])==0){
                    order[--order_index]='-';
                    order_index++;
                    if(dfs(a,sum-a[i])==0){
                        order[--order_index]='*';
                        order_index++;
                        if(dfs(a,sum*a[i])==0){
                            order[--order_index]='/';
                            order_index++;
                            if(dfs(a,sum/a[i])==0){//加减乘除都不行
                                order[--order_index]='\0';//回溯
                                visit[i]=0;//回溯
                                result[--result_index]=0;//回溯
                            }else return 1;
                        }else return 1;
                    }else return 1;
                }else return 1;
            }
        }
        return 0;//找了4个都没找到或者全部数字用完
    }
}
int main() {
    int num[4]={0};
    char str[4][6]={0};
    scanf("%s %s %s %s",str[0],str[1],str[2],str[3]);
    int len;
    for(int i=0;i<4;i++){
        len=strlen(str[i]);
        if(len>2){
            printf("ERROR\n");
            return 0;
        }
        else{
            if(len==2) num[i]=10;
            else{
                if(str[i][0]>='2'&&str[i][0]<='9')
                num[i]=str[i][0]-'0';
                else{
                    switch (str[i][0]) {
                        case 'J':num[i]=11;break;
                        case 'Q':num[i]=12;break;
                        case 'K':num[i]=13;break;
                        case 'A':num[i]=1;break;
                    }
                }
            }
        }
    }
    //初始化结束,开始深搜
    for(int i=0;i<4;i++){
        result[0]=num[i];
        result_index++;
        visit[i]=1;
        if(dfs(num, num[i])==0){
            result_index--;
            result[0]=0;
            visit[i]=0;
        }else{//找到第一个符合条件的算法,输出
            if(result[0]>=2&&result[0]<=9)
            printf("%c",result[0]+'0');
            else{
                switch (result[0]) {
                    case 1:printf("A");break;
                    case 10:printf("10");break;
                    case 11:printf("J");break;
                    case 12:printf("Q");break;
                    case 13:printf("K");break;
                }
            }
            for(int i=0;i<3;i++){
                printf("%c",order[i]);
                if(result[i+1]>=2&&result[i+1]<=9)
                    printf("%c",result[i+1]+'0');
                else{
                    switch (result[i+1]) {
                        case 1:printf("A");break;
                        case 10:printf("10");break;
                        case 11:printf("J");break;
                        case 12:printf("Q");break;
                        case 13:printf("K");break;
                    }
                }
            }
            return 0;
        }
    }
    printf("NONE\n");
    return 0;
}


发表于 2023-04-05 17:07:06 回复(0)
用C写这种代码真的很费时间很折磨。。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MY_CHECK(I,J,K) \
    if((((a I b) J c) K d)==24)\
    {\
        printf("%s" #I "%s" #J "%s" #K "%s\n", poker[a],poker[b],poker[c],poker[d]);\
        return 1;\
    }

char* poker[]=
{
    "INVALID",
    "A",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "10",
    "J",
    "Q",
    "K",
    "INVALID"
};



int my_check(int a,int b,int c,int d)
{
    MY_CHECK(+,+,+);
    MY_CHECK(+,+,-);
    MY_CHECK(+,+,*);
    MY_CHECK(+,+,/);
    
    MY_CHECK(+,-,+);
    MY_CHECK(+,-,-);
    MY_CHECK(+,-,*);
    MY_CHECK(+,-,/);
    
    MY_CHECK(+,*,+);
    MY_CHECK(+,*,-);
    MY_CHECK(+,*,*);
    MY_CHECK(+,*,/);
    
    MY_CHECK(+,/,+);
    MY_CHECK(+,/,-);
    MY_CHECK(+,/,*);
    MY_CHECK(+,/,/);
    
    MY_CHECK(-,+,+);
    MY_CHECK(-,+,-);
    MY_CHECK(-,+,*);
    MY_CHECK(-,+,/);
    
    MY_CHECK(-,-,+);
    MY_CHECK(-,-,-);
    MY_CHECK(-,-,*);
    MY_CHECK(-,-,/);
    
    MY_CHECK(-,*,+);
    MY_CHECK(-,*,-);
    MY_CHECK(-,*,*);
    MY_CHECK(-,*,/);
    
    MY_CHECK(-,/,+);
    MY_CHECK(-,/,-);
    MY_CHECK(-,/,*);
    MY_CHECK(-,/,/);
    
    MY_CHECK(*,+,+);
    MY_CHECK(*,+,-);
    MY_CHECK(*,+,*);
    MY_CHECK(*,+,/);
    
    MY_CHECK(*,-,+);
    MY_CHECK(*,-,-);
    MY_CHECK(*,-,*);
    MY_CHECK(*,-,/);
    
    MY_CHECK(*,*,+);
    MY_CHECK(*,*,-);
    MY_CHECK(*,*,*);
    MY_CHECK(*,*,/);
    
    MY_CHECK(*,/,+);
    MY_CHECK(*,/,-);
    MY_CHECK(*,/,*);
    MY_CHECK(*,/,/);
    
    MY_CHECK(/,+,+);
    MY_CHECK(/,+,-);
    MY_CHECK(/,+,*);
    MY_CHECK(/,+,/);
    
    MY_CHECK(/,-,+);
    MY_CHECK(/,-,-);
    MY_CHECK(/,-,*);
    MY_CHECK(/,-,/);
    
    MY_CHECK(/,*,+);
    MY_CHECK(/,*,-);
    MY_CHECK(/,*,*);
    MY_CHECK(/,*,/);
    
    MY_CHECK(/,/,+);
    MY_CHECK(/,/,-);
    MY_CHECK(/,/,*);
    MY_CHECK(/,/,/);
    
    return 0;
}

int poker2int(char* str)
{
    int i;
    for(i=1;i<14;i++)
        if(!strcmp(str,poker[i]))
            return i;
    return -1;
}

int main(){
    int r = 0;
    
    char aa[10]={0};
    char bb[10]={0};
    char cc[10]={0};
    char dd[10]={0};
    
    scanf("%s %s %s %s\n",aa,bb,cc,dd);
    
    int a = poker2int(aa);
    int b = poker2int(bb);
    int c = poker2int(cc);
    int d = poker2int(dd);
    
    if(a*b*c*d<=0)
    {
        printf("ERROR\n");
        return 0;
    }
    
    r+=my_check(a,b,c,d);
    if(r) return 0;
    r+=my_check(a,b,d,c);
    if(r) return 0;
    r+=my_check(a,c,b,d);
    if(r) return 0;
    r+=my_check(a,c,d,b);
    if(r) return 0;
    r+=my_check(a,d,c,b);
    if(r) return 0;
    r+=my_check(a,d,b,c);
    if(r) return 0;
    
    r+=my_check(b,a,c,d);
    if(r) return 0;
    r+=my_check(b,a,d,c);
    if(r) return 0;
    r+=my_check(b,c,a,d);
    if(r) return 0;
    r+=my_check(b,c,d,a);
    if(r) return 0;
    r+=my_check(b,d,c,a);
    if(r) return 0;
    r+=my_check(b,d,a,c);
    if(r) return 0;
    
    r+=my_check(c,b,a,d);
    if(r) return 0;
    r+=my_check(c,b,d,a);
    if(r) return 0;
    r+=my_check(c,a,b,d);
    if(r) return 0;
    r+=my_check(c,a,d,b);
    if(r) return 0;
    r+=my_check(c,d,a,b);
    if(r) return 0;
    r+=my_check(c,d,b,a);
    if(r) return 0;
    
    r+=my_check(d,b,c,a);
    if(r) return 0;
    r+=my_check(d,b,a,c);
    if(r) return 0;
    r+=my_check(d,c,b,a);
    if(r) return 0;
    r+=my_check(d,c,a,b);
    if(r) return 0;
    r+=my_check(d,a,c,b);
    if(r) return 0;
    r+=my_check(d,a,b,c);
    if(r) return 0;
    
    printf("NONE\n");
    return 0;
}


发表于 2022-01-11 19:46:21 回复(0)