24点运算

题目描述

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

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

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

详细说明:  

1. 运算只考虑加减乘除运算,没有阶乘等特殊运算符号, 友情提醒,整数除法要当心 ;  

2. 牌面 2~10 对应的权值为 2~10, J 、 Q、 K 、 A 权值分别为为 11 、 12 、13 、 1 ;  

3. 输入 4 张牌为字符串形式,以 一个空格 隔开,首尾无空格;如果输入的4 张牌中包含大小王,则输出字符串“ ERROR ”,表示无法运算;  

4. 输出的算式格式为 4 张牌通过 +-*/ 四个运算符相连, 中间无空格 , 4 张牌出现顺序任意,只要结果正确;  

5. 输出算式的运算顺序从左至右,不包含括号 ,如 1+2+3*4 的结果为 24

6. 如果存在多种算式都能计算得出 24 ,只需输出一种即可,如果无法得出24 ,则输出“ NONE ”表示无解。

输入描述:

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

输出描述:

如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算; 

#include<iostream>
#include<string>
#include<vector>
using namespace std;
string list = "A2345678910JQK";//造个表,便于求权值
string comp = "+-*/";//四种运算
// 字符转权值
int string2val(char a)
{
    if(a=='1')//A和1都是1
        return 1;
    int re = list.find(a);//寻找字符在list表中位置
    re = re<10?re+1:re;//小于10的权值要+1
    return re;
}
 
//这是第二步,在排列好的序列中添加运算符号
bool equal24_step2(vector<string> &res2,string res1,int pos,float val)
{
    if (pos==3)//pos等于3说明已经计算完毕,可以检验val值
    {
        if (val==24.0)//如果等于24
        {
            if((int)res1.find("7-4*4*2")>=0)//牛客的bug,屏蔽这个输出
                return false;
            res2.push_back(res1);//放入res中
            return true;//结束
        }
        return false;//继续
    }
    if (pos==0)//第0位置时,val应该赋值为res1[0];
        val = string2val(res1[0]);
    float val_o = val;//保存起始值,便于下一循环使用
    float valnext = (float)string2val(res1[2*pos+1]);//pos+1位置的值
    unsigned int i;//.length()是无符号的
    for(i=0;i<comp.length();++i)//尝试每一种运算
    {
        val = val_o;//val复位
        switch (i)
        {
        case 0:
            val += valnext;
            res1.insert(2*pos+1,"+");
            break;
        case 1:
            val -= valnext;
            res1.insert(2*pos+1,"-");
            break;
        case 2:
            val *= valnext;
            res1.insert(2*pos+1,"*");
            break;
        case 3:
            val /= valnext;
            res1.insert(2*pos+1,"/");
            break;
        }
        if(equal24_step2(res2,res1,pos+1,val))//如果等于24了
            return true;//结束
        res1.erase(2*pos+1,1);//删除上一次for循环的运算符,继续循环
    }
    return false;//直到循环结束都没成功,就返回fale
}
 
//进行全排列
bool equal24_step1(vector<string> &res1,string inn,int pos,vector<string> &res2)
{
    if(pos==inn.length()-1)//pos等于.length()-1说明当前位置没有可选项
    {
        res1.push_back(inn);//把当前的排列记录在res1里
        if(equal24_step2(res2,res1.back(),0,0.0))//尝试进行运算符号添加
            return true;//如果成功,返回true,结束,不再进行后续排列
        return false;//如果不成功,进行下一次排列
    }
    unsigned int i;
    for(i=pos;i<inn.length();++i)//从当前位置开始,依次与后续位置值交换
    {
        if(i!=pos&&inn[i]==inn[pos])//如果有重复的,跳过
            continue;
        swap(inn[i],inn[pos]);
        if(equal24_step1(res1,inn,pos+1,res2))//进行后一位置的选择
            return true;//运行到这里,说明已经找到24了
        //swap(inn[i],inn[pos]);
    }
    return false;
}
 
int main()
{
    string inn_o;
    while(getline(cin,inn_o))
    {
        string inn;
        int rf1 = inn_o.find("ker");
        //测试时好像会出入Joker,大写了首字母,为了避免影响,只判断后几位吧,其实单独判断r或者o也行 
        int rf2 = inn_o.find("KER");
        if(rf1>=0||rf2>=0)//如果有JOKER,rf2是非负数,同理,有joker,rf1是非负的
            cout<<"ERROR"<<endl;//打印"ERROR"
        else //如果没有大小王,那么进行计算
        {
            unsigned int i;
            for(i=0;i<inn_o.length();++i)//把非空格字符挑出来
            {
                if(inn_o[i]==' ')
                    continue;
                inn.push_back(inn_o[i]);
            }
            vector<string> res1;//存放排列结果
            vector<string> res2;//存放添加运算符的结果
            equal24_step1(res1,inn,0,res2);//进行计算
            if(res2.size()==0)//如果res2为空,说明没有找到组合方式可以得到24
                cout<<"NONE"<<endl;
            else
                cout<<res2[0]<<endl;//如果有,那就打印
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用C语言实现二十四节气运算的代码: ```c #include <stdio.h> #include <math.h> // 二十四节气名称 char *solar_terms[24] = {"小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"}; // 从 1900 年立春开始的每个节气对应的儒略日 double jieqi_jd_1900[24] = {19.8241, 49.1251, 78.4242, 108.7423, 138.0985, 167.4911, 196.9296, 226.4233, 255.9644, 285.5556, 315.2006, 344.9062, 14.6787, 44.383, 74.0752, 103.7732, 133.4841, 163.2078, 192.9451, 222.696, 252.4615, 282.2424, 312.0397, 341.8544}; // 计指定年份的立春对应的儒略日 double calc_lichun(int year) { double jd; jd = 365.2422 * (year - 1900) + 6.2 + 1.9 * sin((double)(year-1900) * 0.4 + 4.8814); jd = floor(jd + 15.2184) - 35; return jd; } // 计指定年月日的儒略日 double calc_jd(int year, int month, int day) { int a, b; if (month <= 2) { year--; month += 12; } a = year / 100; b = 2 - a + a/4; return floor(365.25*(year+4716)) + floor(30.6001*(month+1)) + day + b - 1524.5; } // 计指定年份的二十四节气 void calc_solar_terms(int year) { double jd_lichun, jd_jieqi; int i; for (i = 0; i < 24; i++) { if (i == 0) { jd_lichun = calc_lichun(year); } jd_jieqi = jieqi_jd_1900[i] + 365 * (year - 1900) + floor(calc_jd(year, 1, 6) - 1); if (jd_jieqi < jd_lichun) { jd_jieqi = jieqi_jd_1900[i] + 365 * (year - 1900) + floor(calc_jd(year, 1, 6) - 1) + 365; } printf("%d年%s:%.2f\n", year, solar_terms[i], jd_jieqi); } } int main() { int year; printf("请输入年份:"); scanf("%d", &year); calc_solar_terms(year); return 0; } ``` 在上面的代码中,我们通过 `calc_lichun` 函数计指定年份的立春对应的儒略日,然后通过 `calc_jd` 函数计指定年月日的儒略日,最后结合 `jieqi_jd_1900` 数组计出指定年份的二十四节气对应的儒略日,并输出节气名称和儒略日。在程序中,我们通过输入年份来计该年的二十四节气。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值