美文网首页
装水问题进化版—C++

装水问题进化版—C++

作者: 53324d792ce6 | 来源:发表于2016-03-31 22:30 被阅读100次

    有4个瓶子,它们的容量分别是:

    10升,6升, 5升, 4升

    开始的状态是 [10,0,0,0],也就是说:第一个瓶子满着,其它的都空着。
    允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。这样的一次倒酒动作称为1次操作。
    假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现?

    输入:最终状态 输出:最小操作次数(如无法实现,则输出-1)

    例如:
    输入:10 0 0 0
    输出:0
    输入:7 3 0 0
    输出:8

    利用map完成穷搜

    //10升, 6升, 5升,4升
    #include <iostream>
    #include <map>
    #include <limits>
    int capacity[] = { 10, 6, 5, 4 };
    class state
    {
    public:
        state(int _b10, int _b6, int _b5, int _b4)
            :count(0), value(_b10 * 1000 + _b6 * 100 + _b5 * 10 + _b4)
        {
        }
        bool operator<(state rhs)const
        {
            return value < rhs.value;
        }
        int getvalue()const
        {
            return value;
        }
        short count;
    protected:
        short value;
    };
    std::map<int,state> open, close;
    void int2array(int content[], state s)
    {
        int svalue = s.getvalue();
        content[0] = svalue / 1000;
        content[1] = svalue % 1000 / 100;
        content[2] = svalue % 100 / 10;
        content[3] = svalue % 10;
    }
    int array2int(int content[])
    {
        return content[0] * 1000 + content[1] * 100
            + content[2] * 10 + content[3];
    }
    //一步转移状态
    void derive(std::pair<int, state> sp)
    {
        int c[4], t[4];
        int2array(c, sp.second);
        for (int i = 0; i < 4; ++i) // the bottle to pour from
        {
            if (c[i] == 0)
                continue; // no action on empty bottle
            for (int j = 0; j < 4; ++j) // the bottle to pour to
            {
                if (j == i || c[j] == capacity[j]) // don't pour to self or full bottle
                    continue;
                //now we can derive a new state
                //state s=*this;
                //++s.count;
                int balance = capacity[j] - c[j];
                t[0] = c[0];
                t[1] = c[1];
                t[2] = c[2];
                t[3] = c[3];
                if (c[i] > balance) // source has more than target can hold
                    t[i] -= balance, t[j] = capacity[j];
                else // target can hold everything currently in source
                    t[j] += t[i], t[i] = 0;
                state si(t[0], t[1], t[2], t[3]);
                si.count = sp.second.count + 1;
                auto p = open.find(array2int(t));
                auto q = close.find(array2int(t));
                if (p != open.end()) // might encounter a better state
                {
                    if (p->second.count > si.count)
                        p->second.count = si.count;
                }
                else if (q == close.end())
                {
                    open.insert(std::pair<int, state>(array2int(t),si));
                }
            }
        }
    }
    int main() {
        int n = 4;
        int input;
        int min = INT_MAX;
        int initvalue = 1;
        //输入初始状态
        open.insert(std::pair<int, state>(10000, state(10, 0, 0, 0)));
        //输入的四个数变为一个数
        for (int i = 0; i < n; i++)
        {
            std::cin >> input;
            if (i == 0)
                initvalue = input;
            else
                initvalue = initvalue * 10 + input;
        }
        //穷搜整个空间,取出open状态加入close,新状态加入open
        while (!open.empty())
        {
            auto p = open.begin();
            auto s = *p;
            close.insert(s);
            open.erase(p);
            derive(s);
        }
        //printf 
        for (auto i = close.begin(); i != close.end(); ++i)
        {
            std::cout << i->first << " " << i->second.count << std::endl;
        }
        auto i = close.find(initvalue);
        if(i != close.end())
            if (min > i->second.count)
                min = i->second.count;
        if (min == INT_MAX)
            std::cout << -1 << std::endl;
        std::cout << min << std::endl;
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:装水问题进化版—C++

          本文链接:https://www.haomeiwen.com/subject/phtylttx.html