HDOJ 1427(dfs) 速算24点

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1427

思路分析:

题目要求判断是否存在一种运算组合使得4个数的计算结果为24,因为搜索的层次为3层,不需要选择出最短的路径,采用dfs更有效;

拓展状态时,从当前状态拥有的数中选取两个进行某种运算(因为两个数之间存在大小关系,所以对于除法与减法来说,运算顺序一定,

大的数为被减数或被除数;加法与乘法具有交换律,相对顺序没有影响),如果可以进行运算且运算结果满足题目要求,则该状态可以

拓展,如此拓展状态,直到检测到存在一种可能的运算顺序使运算结果为24。

 

代码如下:

#include <iostream>
#include <cmath>
using namespace std;

struct Cards
{
    int num[4];
    int len;
};

int Max(int lhs, int rhs) { return lhs > rhs ? lhs : rhs; }
int Min(int lhs, int rhs) { return lhs > rhs ? rhs : lhs; }
double Calculate(int i, int t_lhs, int t_rhs, bool &ok)
{
    int lhs, rhs;

    lhs = Max(t_lhs, t_rhs);
    rhs = Min(t_lhs, t_rhs);
    if (i == 0) return lhs + rhs;
    if (i == 1) return lhs - rhs;
    if (i == 2) return lhs * rhs;
    if (i == 3)
    {
        if (rhs != 0 && lhs >= rhs && lhs % rhs == 0)
            return lhs / rhs;
        else
        {
            ok = false;
            return 0;
        }
    }
}

void dfs(Cards start, bool &find_ans)
{
    if (start.len == 1)
    {
        if (start.num[0] == 24)
            find_ans = true;
        return;
    }
    else
    {
        int len = start.len;

        for (int i = 0; i < len; ++i)
        {
            for (int j = i + 1; j < len; ++j)
            {
                int count = 0;
                int lhs = start.num[i];
                int rhs = start.num[j];
                Cards next;

                for (int k = 0; k < len; ++k)
                {
                    if (k != i && k != j)
                        next.num[count++] = start.num[k];
                }
                next.len = count + 1;

                for (int k = 0; k < 4; ++k)
                {
                    bool ok = true;
                    double result = Calculate(k, lhs, rhs, ok);

                    if (find_ans)
                        return;
                    if (!ok || result != (int)result)
                        continue;
                    next.num[count] = result;
                    dfs(next, find_ans);
                }
            }
        }
    }
}

int StrToInt(char *s)
{
    int result = 0;
    if (s[0] == 'A') result = 1;
    else if (s[0] == 'J') result = 11;
    else if (s[0] == 'Q') result = 12;
    else if (s[0] == 'K') result = 13;
    else if (s[0] == '1' && s[1] == '0') result = 10;
    else result = s[0] - '0';

    return result;
}

int main()
{
    Cards start;
    bool find_ans;
    char temp[5];

    while (scanf("%s", &temp) != EOF)
    {
        find_ans = false;
        start.len = 4;
        start.num[0] = StrToInt(temp);
        for (int i = 1; i < 4; ++i)
        {
            scanf("%s", &temp);
            start.num[i] = StrToInt(temp);
        }

        dfs(start, find_ans);
        if (find_ans)
            cout << "Yes
";
        else
            cout << "No
";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/tallisHe/p/4498822.html