24点计算

  • 规则
    随机输入四个1到13(也就是扑克牌中A-K)的数字,利用加、减、乘和除对这四个数做运算最终计算得到24,这四个数都需要用到,而且只能使用一次。

  • 思路

    • 四个[1 - 13]的数字,a、b、c、d,可用符号+、-、*、/
    • 两两数字之间存在6个结果:{a+b},{a-b},{b-a},{a*b},{a/b},{b/a}
    • 四个数存在三个符号,也就是存在6*6*6=216种结果
    • 四个数字存在4的阶乘=24种组合:
      {a,b,c,d},{a,b,d,c},{a,c,b,d},{a,c,d,b},{a,d,b,c},{a,d,c,b},
      {b,a,c,d},{b,a,d,c},{b,c,d,a},{b,c,a,d},{b,d,a,c},{b,d,c,a},
      {c,a,b,d},{c,a,d,b},{c,b,d,a},{c,b,a,d},{c,d,a,b},{c,d,b,a},
      {d,a,b,c},{d,a,c,b},{d,b,c,a},{d,b,a,c},{d,c,b,a},{d,c,a,b},
    • 24种组合,每种组合存在216种结果,也就是存在24*216=5184种结果(当两数字相同存在相同结果的情况)
  • 代码:

/*************************************************************************
    > File Name: twentyfour.cc
    > Mail: peterliu0725@163.com
 ************************************************************************/

#include <set>
#include <vector>
#include <iostream>
#include <utility>
#include <stdio.h>
#include <stdlib.h>

// 记录两数的操作,例如 "(4 + 3)"
std::string tostring(float a, float b, char c)
{
    char buf[32] = {0};
    sprintf(buf, "(%.0f %c %.0f)", a, c, b);
    return std::string(buf);
}

// 记录前面两数的操作与第三数的操作,或者前面三数与第四个数的操作
// 例如 "((4 + 3) * 2)"
std::string tostring(std::string a, std::string b, char c)
{
    char buf[32] = {0};
    sprintf(buf, "(%s %c %s)", a.c_str(), c, b.c_str());
    return std::string(buf);
}

// 把浮点数变为字符串,例如 3.5 -> "3.5"
std::string tostring(float a)
{
    char buf[32] = {0};
    sprintf(buf, "%.0f", a);
    return std::string(buf);
}

// 把两数的结果,一共6钟结果和他们的操作返回出去
// 例如:<7, "3 + 4">,<-1,"3 - 4">,<1, "4 - 3">,<12, "3 * 4">,<0.75, "3 / 4">,<1.33333,"4/3">
std::vector<std::pair<float, std::string>> result(float a, float b)
{
    std::vector<std::pair<float, std::string>> r;
    r.push_back(std::pair<float, std::string>(a + b, tostring(a, b, '+')));
    r.push_back(std::pair<float, std::string>(a * b, tostring(a, b, '*')));
    r.push_back(std::pair<float, std::string>(a - b, tostring(a, b, '-')));
    r.push_back(std::pair<float, std::string>(b - a, tostring(b, a, '-')));
    r.push_back(std::pair<float, std::string>(a / b, tostring(a, b, '/')));
    r.push_back(std::pair<float, std::string>(b / a, tostring(b, a, '/')));
    return r;
}

std::vector<std::pair<float, std::string>> result(float a, float b, std::string s)
{
    std::vector<std::pair<float, std::string>> r;
    r.push_back(std::pair<float, std::string>(a + b, tostring(s, tostring(b), '+')));
    r.push_back(std::pair<float, std::string>(a * b, tostring(s, tostring(b), '*')));
    r.push_back(std::pair<float, std::string>(a - b, tostring(s, tostring(b), '-')));
    r.push_back(std::pair<float, std::string>(b - a, tostring(tostring(b), s, '-')));
    r.push_back(std::pair<float, std::string>(a / b, tostring(s, tostring(b), '/')));
    r.push_back(std::pair<float, std::string>(b / a, tostring(tostring(b), s, '/')));
    return r;
}

std::vector<std::pair<float, std::string>> result(std::vector<std::pair<float, std::string>> array, float b)
{
    std::vector<std::pair<float, std::string>> r;
    for (auto m : array) {
        std::vector<std::pair<float, std::string>> rr = result(m.first, b, m.second);
        r.insert(r.end(), rr.begin(), rr.end());
    }
    return r;
}

std::set<std::string> all_result;
void show_result(std::vector<float> v)
{
    std::vector<std::pair<float, std::string>> r;
    if (v.size() < 2) {
        return;
    }

    r = result(v[0], v[1]);
    for (auto it = v.begin() + 2; it != v.end(); ++it) {
        r = result(r, *it);
    }

    for (auto m : r) {
        if (24 == m.first) {
            all_result.insert(m.second);
        }
    }
}

std::vector<std::vector<int>> four_factorial()
{
    std::vector<std::vector<int>> vv;

    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j) {
            for (int k = 0; k < 4; ++k) {
                for (int z = 0; z < 4; ++z) {
                    if (i != j && i != k && i != z &&
                            j != k && j != z &&
                            k != z) {
                        std::vector<int> v;
                        v.push_back(i);
                        v.push_back(j);
                        v.push_back(k);
                        v.push_back(z);
                        vv.push_back(v);
                    }
                }
            }
        }
    }
    return vv;
}

std::vector<float> bind(float* user_input, std::vector<int> order)
{
    std::vector<float> v;
    for (int index : order) {
        v.push_back(user_input[index]);
    }
    return v;
}

int main(int argc, char* argv[])
{
    if (argc != 5) {
        printf("%s four valid digital\n", argv[0]);
        return 1;
    }

    float input_digital[32] = {0};
    printf("input number is :");
    for (int i = 1; i < 5; ++i) {
        int number = atoi(argv[i]);
        if (number < 1 || number > 13) {
            std::cout << "Invalid digital " << number << "\n";
            return -1;
        }
        printf(" %d ", number);
        input_digital[i - 1] = static_cast<float>(number);
    }
    printf("\n");

    for (std::vector<int> v : four_factorial()) {
        show_result(bind(&input_digital[0], v));
    }

    for (std::string s : all_result) {
        std::cout << s << std::endl;
    }

    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值