《24点游戏》

 《编程之美》1.16节《24点游戏》,这个不多说了,大家从小玩到大的。书中解法一用了枚举的方法,依次求解出所有7680种表达式的值;解法二用了分治的思想来优化算法,我写的算法就是根据解法二来的,书中的伪代码只能判断N个数能否求出24,而我改进之后就可以输出满足题意的表达式了

  算法中我用到C++ STL中的set容器,因为set中的元素都是非重的。

//实现N个数通过简单的运算得到结果24.

CODE

//24Game
//2010-01-17
//by roovent

#include <iostream>
#include <sstream>
#include <string>
#include <set>
#define N 4
#define M (1<<N)
#define TARGET 24

using namespace std;

struct Element
{
    double num;
    string expression;

    friend bool operator< (const Element& a, const Element& b)
    {
        return a.num < b.num;
    }
};

//--全局变量
set<Element> result[M];
//--全局变量结束

set<Element> Process(const int x, int* nums)
{
    set<Element> s;
    for(int i = 1; i < x; ++i)
    {  
        if((i|x) == x && x-i>i) //i是x的子集,x-i是其补集,确保子集与其补集不重复运算
        {
            for(set<Element>::iterator p = result[i].begin(); p != result[i].end(); ++p)
            {
                for(set<Element>::iterator q = result[x-i].begin(); q != result[x-i].end(); ++q)
                {
                    Element e;
                    double dbA = (*p).num;
                    double dbB = (*q).num;
                    string strA = (*p).expression;
                    string strB = (*q).expression;

                    e.num = dbA + dbB;
                    e.expression = "(" + strA + " + " + strB + ")";
                    s.insert(e);

                    e.num = dbA - dbB;
                    e.expression = "(" + strA + " - " + strB + ")";
                    s.insert(e);

                    e.num = dbB - dbA;
                    e.expression = "(" + strB + " - " + strA + ")";
                    s.insert(e);

                    e.num = dbA * dbB;
                    e.expression = "(" + strA + " * " + strB + ")";
                    s.insert(e);
                   
                    if(dbB != 0)
                    {
                        e.num = dbA / dbB;
                        e.expression = "(" + strA + " / " + strB + ")";
                        s.insert(e);
                    }
                   
                    if(dbA != 0)
                    {
                        e.num = dbB / dbA;
                        e.expression = "(" + strB + " / " + strA + ")";
                        s.insert(e);
                    }
                }
            }
        }
    }
    return s;
}

bool Solve(int* nums)
{
    for(int i = 0; i < M; ++i)
    {
        result[i].clear();
    }

    for(int i = 0; i < N; ++i)
    {
        stringstream ss;
        ss<<nums[i]; //将整型转化为字符串
        Element e = {nums[i], ss.str()};
        result[1<<i].insert(e);
    }

    for(int i = 1; i < M; ++i)
    {
        if(result[i].empty())
            result[i] = Process(i, nums);
    }

    Element e = {TARGET, ""};
    return result[M-1].find(e) != result[M-1].end();
}

int main()
{
    int nums[N] =
        {5,5,5,1};
        //{3,3,7,7};
        //{3,3,8,8};
        //{1,4,5,6};
        //{3,8,8,10};
        //{4,4,10,10};
        //{9,9,6,2};
   
    cout<<"Problem: ";
    for(int i = 0; i < N - 1; ++i)
    {
        cout<<nums[i]<<", ";
    }
    cout<<nums[N-1]<<endl;

    if(Solve(nums))
    {
        Element e = {TARGET, ""};
        cout<<"Solution: "<<(*(result[M-1].find(e))).expression << endl;
    }
    else
    {
        cout<<"No Solution"<<endl;
    }
    return 0;
}

你可能感兴趣的:(《24点游戏》)