USACO-1.4.3-Mother's Milk

来源:互联网 发布:手机淘宝怎么退款过程 编辑:程序博客网 时间:2024/06/05 17:21

Mother’s Milk解题报告

题目链接:http://train.usaco.org/usacoprob2?a=JfbzzkHQu8y&S=milk3

题目大意:FJ有三个牛奶桶,分别有A, B, C的容量。每个桶的容量都在1-20之间。一开始的时候A和B的桶是空着的,C中装满的牛奶。然后,他会把这些牛奶倒来倒去,在倒牛奶的过程中不会有任何的牛奶损失。一旦他开始倒牛奶,要么当前桶里的牛奶全部倒完了,要么目标桶的牛奶满了,他才会停下来。那么,他重复这个过程,最后C桶中会剩下多少牛奶(把所有的可能性列出来),并且A桶必须是空的。

解题思路:nocow不知道为啥上不去了,一开始没思路。后来看了一下这个小结的主题是搜索,于是就往搜索的方面考虑。因为一共就三个桶,因此每次操作一共只有六种可能: A-B, A-C, B-A, B-C, C-A, C-B。只需要把当前的状态记录下来,并且在每个状态下遍历下一个可能的状态,用堆栈就很容易实现。对每一个状态进行判断,如果这个状态下A桶是空着的,那么这时候C桶中的牛奶量就是一种可能。下面是代码:

#include <iostream>#include <cstring>#include <stack>#include <fstream>using namespace std;struct bucketState{    int A, B, C;    void copy(bucketState bs)    {        A = bs.A;        B = bs.B;        C = bs.C;    }};bool ans[21];  //用来记录C中可能的牛奶量bool state[21][21][21];  //用来标记状态stack<bucketState> bState;int liter[3];//把牛奶从一个桶倒进另一个桶,pos用来判断目标桶是哪个桶void PourMilk(int &a, int &b, int pos){    if (a == 0 || b == liter[pos])        return;    if (b + a <= liter[pos])    {        b = a + b;        a = 0;    }    else    {           a = a - (liter[pos] - b);        b = liter[pos];    }}void GetAns(){    bucketState bTop, bTmp;    while (bState.empty() == 0)    {        bTop = bState.top();        bState.pop();        //A->B        bTmp.copy(bTop);        PourMilk(bTmp.A, bTmp.B, 1);        if (state[bTmp.A][bTmp.B][bTmp.C] == 0)        {            bState.push(bTmp);            state[bTmp.A][bTmp.B][bTmp.C] = 1;        }        if (bTmp.A == 0)            ans[bTmp.C] = 1;        //A->C        bTmp.copy(bTop);        PourMilk(bTmp.A, bTmp.C, 2);        if (state[bTmp.A][bTmp.B][bTmp.C] == 0)        {            bState.push(bTmp);            state[bTmp.A][bTmp.B][bTmp.C] = 1;        }        if (bTmp.A == 0)            ans[bTmp.C] = 1;        //B->A        bTmp.copy(bTop);        PourMilk(bTmp.B, bTmp.A, 0);        if (state[bTmp.A][bTmp.B][bTmp.C] == 0)        {            bState.push(bTmp);            state[bTmp.A][bTmp.B][bTmp.C] = 1;        }        if (bTmp.A == 0)            ans[bTmp.C] = 1;        //B->C        bTmp.copy(bTop);        PourMilk(bTmp.B, bTmp.C, 2);        if (state[bTmp.A][bTmp.B][bTmp.C] == 0)        {            bState.push(bTmp);            state[bTmp.A][bTmp.B][bTmp.C] = 1;        }        if (bTmp.A == 0)            ans[bTmp.C] = 1;        //C->A        bTmp.copy(bTop);        PourMilk(bTmp.C, bTmp.A, 0);        if (state[bTmp.A][bTmp.B][bTmp.C] == 0)        {            bState.push(bTmp);            state[bTmp.A][bTmp.B][bTmp.C] = 1;        }        if (bTmp.A == 0)            ans[bTmp.C] = 1;        //C->B        bTmp.copy(bTop);        PourMilk(bTmp.C, bTmp.B, 1);        if (state[bTmp.A][bTmp.B][bTmp.C] == 0)        {            bState.push(bTmp);            state[bTmp.A][bTmp.B][bTmp.C] = 1;        }        if (bTmp.A == 0)            ans[bTmp.C] = 1;    }}int main(){    ifstream fin("milk3.in");    ofstream fout("milk3.out");    while (fin >> liter[0] >> liter[1] >> liter[2])    {        memset(ans, 0, sizeof(ans));        memset(state, 0, sizeof(state));        ans[liter[2]] = 1; //初始状态肯定能得到        bucketState iniState;        iniState.A = 0;        iniState.B = 0;        iniState.C = liter[2];        bState.push(iniState);        state[0][0][liter[2]] = 1;        GetAns();        for (int i = 0; i < liter[2]; ++i)        {            if (ans[i] == 1)                fout << i << ' ';        }        fout << liter[2] << endl;    }    return 0;}
0 0
原创粉丝点击