USACO 1.4 Mother's Milk

Mother‘s Milk

Farmer John has three milking buckets of capacity A, B, and C liters. Each of the numbers A, B, and C is an integer from 1 through 20, inclusive. Initially, buckets A and B are empty while bucket C is full of milk. Sometimes, FJ pours milk from one bucket to another until the second bucket is filled or the first bucket is empty. Once begun, a pour must be completed, of course. Being thrifty, no milk may be tossed out.

Write a program to help FJ determine what amounts of milk he can leave in bucket C when he begins with three buckets as above, pours milk among the buckets for a while, and then notes that bucket A is empty.

PROGRAM NAME: milk3

INPUT FORMAT

A single line with the three integers A, B, and C.

SAMPLE INPUT (file milk3.in)

8 9 10

OUTPUT FORMAT

A single line with a sorted list of all the possible amounts of milk that can be in bucket C when bucket A is empty.

SAMPLE OUTPUT (file milk3.out)

1 2 8 9 10

SAMPLE INPUT (file milk3.in)

2 5 10

SAMPLE OUTPUT (file milk3.out)

5 6 7 8 9 10

题意: Farmer John有三个桶A,B,C,输入三个桶的容积;开始时桶A和第桶B为空,桶C为满。Farmer John要做pours milk操作,把桶x的牛奶导入桶y中,除非桶y被倒满或桶x已倒空,一次操作算作结束。进行n次倒牛奶操作改变C桶中牛奶的余量,但要求终止时A桶要为空。问:C桶中牛奶的余量一共有多少种情况。

题解: 一共有6种操作 A->B;A->C; B->A;B->C; C->A;C->B;用宽搜就可以了做出来,但感觉这次我写的代码好丑,过于冗余。

ps:本人大三狗一枚,正在持续更新博客,文章里有任何问题,希望各位网友可以指出。若有疑问也可在评论区留言,我会尽快回复。希望能与各位网友互相学习,谢谢
/*
ID: cxq_xia1
PROG: milk3
LANG: C++
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>

using namespace std;
struct node
{
    int a,b,c;
    friend bool operator < (node x,node y)
    {
        return x.c > y.c;
    }
};
bool flag[21][21][21];
queue<node> q;
priority_queue<node> ans;
int A,B,C,cnt=0;
node tmp1,tmp2;
void BFS()
{
    tmp1.a=0;tmp1.b=0;tmp1.c=C;
    flag[tmp1.a][tmp1.b][tmp1.c]=true;
    q.push(tmp1);

    while(!q.empty())
    {
        tmp1=q.front();
        q.pop();
        if(tmp1.a==0)
        {
            ans.push(tmp1);
            cnt++;
        }

        if(tmp1.a!=0)
        {
            if(tmp1.b+tmp1.a<=B)
            {
                tmp2.a=0;
                tmp2.b=tmp1.b+tmp1.a;
                tmp2.c=tmp1.c;
            }
            else
            {
                tmp2.a=tmp1.a-(B-tmp1.b);
                tmp2.b=B;
                tmp2.c=tmp1.c;
            }
             if(!flag[tmp2.a][tmp2.b][tmp2.c])
            {
                flag[tmp2.a][tmp2.b][tmp2.c]=true;
                q.push(tmp2);
            }

            if(tmp1.c+tmp1.a<=C)
            {
                tmp2.a=0;
                tmp2.b=tmp1.b;
                tmp2.c=tmp1.c+tmp1.a;
            }
            else
            {
                tmp2.a=tmp1.a-(C-tmp1.c);
                tmp2.b=tmp1.b;
                tmp2.c=C;
            }
             if(!flag[tmp2.a][tmp2.b][tmp2.c])
            {
                flag[tmp2.a][tmp2.b][tmp2.c]=true;
                q.push(tmp2);
            }

        }

        if(tmp1.b!=0)
        {
            if(tmp1.a+tmp1.b<=A)
            {
                tmp2.a=tmp1.a+tmp1.b;
                tmp2.b=0;
                tmp2.c=tmp1.c;
            }
            else
            {
                tmp2.a=A;
                tmp2.b=tmp1.b-(A-tmp1.a);
                tmp2.c=tmp1.c;
            }
             if(!flag[tmp2.a][tmp2.b][tmp2.c])
            {
                flag[tmp2.a][tmp2.b][tmp2.c]=true;
                q.push(tmp2);
            }

            if(tmp1.c+tmp1.b<=C)
            {
                tmp2.a=tmp1.a;
                tmp2.b=0;
                tmp2.c=tmp1.c+tmp1.b;
            }
            else
            {
                tmp2.a=tmp1.a;
                tmp2.b=tmp1.b-(C-tmp1.c);
                tmp2.c=C;
            }
             if(!flag[tmp2.a][tmp2.b][tmp2.c])
            {
                flag[tmp2.a][tmp2.b][tmp2.c]=true;
                q.push(tmp2);
            }
        }

        if(tmp1.c!=0)
        {
            if(tmp1.a+tmp1.c<=A)
            {
                tmp2.a=tmp1.a+tmp1.c;
                tmp2.b=tmp1.b;
                tmp2.c=0;
            }
            else
            {
                tmp2.a=A;
                tmp2.b=tmp1.b;
                tmp2.c=tmp1.c-(A-tmp1.a);
            }
             if(!flag[tmp2.a][tmp2.b][tmp2.c])
            {
                flag[tmp2.a][tmp2.b][tmp2.c]=true;
                q.push(tmp2);
            }

            if(tmp1.b+tmp1.c<=B)
            {
                tmp2.a=tmp1.a;
                tmp2.b=tmp1.b+tmp1.c;
                tmp2.c=0;
            }
            else
            {
                tmp2.a=tmp1.a;
                tmp2.b=B;
                tmp2.c=tmp1.c-(B-tmp1.b);
            }
             if(!flag[tmp2.a][tmp2.b][tmp2.c])
            {
                flag[tmp2.a][tmp2.b][tmp2.c]=true;
                q.push(tmp2);
            }
        }
    }
}

int main()
{
    freopen("milk3.in","r",stdin);
    freopen("milk3.out","w",stdout);

    memset(flag,false,sizeof(flag));
    cin >> A >> B >> C;
    BFS();
    node tmp;
    int i;
    while(!ans.empty())
    {
        tmp=ans.top();
        ans.pop();
        i++;
        if(i!=cnt)
            cout << tmp.c << " ";
        else
            cout << tmp.c <<endl ;
    }
    return 0;
}

  

USACO 1.4 Mother's Milk

时间: 2024-10-11 23:10:41

USACO 1.4 Mother's Milk的相关文章

USACO Section1.4 Mother&#39;s Milk 解题报告

milk3解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------------------------------------------------------------------------------------------[题目] 有三个桶,容量分别是A.B.C,开始C桶是满的. 你可以不断将某个桶的奶倒到另一个桶里,但只允许全倒过去,或者将后者倒满,前者留下

usaco Mother&#39;s Milk

给了三个木桶的容量,起始状态下C木桶装满,然后三个木桶相互倒牛奶,问当A木桶为空时的C木桶的牛奶体积的可能情况. 直接深度优先搜索,模拟三个木桶相互倒的情况 相互倒得情况本可以写的更简洁,但为了可阅读性我并没有这么干 不过这道题在本机上调试时,我曾将一个我认为无关紧要的地方写错,因为两个数组大小一样,所以在sizeof的括号中写了另外一个,结果却出不了正解. 有机会要好好查查memcyp函数的用法. /* ID: modengd1 PROG: milk3 LANG: C++ */ #includ

USACO Mother&#39;s Milk(bfs)

题目请点我 题解: 水杯倒水的问题很经典,套路也是一样的,bfs找出所有状态.这道题的关键在于每次都应该进行六次的倒水尝试,细心一点.PS:三维数组表示状态真的很方便. 代码实现: /* ID: eashion LANG: C++ TASK: milk3 */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #

【USACO】Mother&#39;s Milk(搜索)

一开始还在想去重的问题,结果发现后台数据貌似没有重复的情况= = /* ID: 18906421 LANG: C++ PROG: milk3 */ #include<cmath> #include<cstdio> #include<vector> #include<algorithm> using namespace std; const int maxn = 25; int vis[maxn][maxn][maxn] = {0}; vector<in

洛谷 P1215 [USACO1.4]母亲的牛奶 Mother&#39;s Milk

题目描述 农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的.有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了.当然每一次灌注都是完全的.由于节约,牛奶不会有丢失. 写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性. 输入输出格式 输入格式: 单独的一行包括三个整数A,B和C. 输出格式: 只有一行,升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性. 输入输出样例 输入样例#1:

luogu P1215 [USACO1.4]母亲的牛奶 Mother&#39;s Milk

题目描述 农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的.有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了.当然每一次灌注都是完全的.由于节约,牛奶不会有丢失. 写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性. 输入输出格式 输入格式: 单独的一行包括三个整数A,B和C. 输出格式: 只有一行,升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性. 输入输出样例 输入样例#1:

Mother&#39;s Milk

本题中, 三个桶,因此就是6种:A->B A->C B->A B->C C->A C->B.所有转移都考虑一遍即可. 以A->B来说,这样转移之后状态是什么呢?A的 牛奶数应该是max(0, a+b-B),其中a,b是A和B桶中原来牛奶的数量,A,B是A和B桶的容量.B的牛奶数是 min(a+b, B),其他的以此类推.本题就差不多了.~ 代码: /* ID:Andy Chen PROG: milk3 LANG: C++ */ #include <cstdi

[USACO1.4]母亲的牛奶 Mother&#39;s Milk

题目 题目描述 农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的.有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了.当然每一次灌注都是完全的.由于节约,牛奶不会有丢失. 写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性. 输入输出格式 输入格式: 单独的一行包括三个整数A,B和C. 输出格式: 只有一行,升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性. 输入输出样例 输入样例

$P1215 [USACO1.4]母亲的牛奶 Mother&#39;s Milk$

\(problem\) 搜索 找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性. 显然 我们需要一个数组来判重 表示这种状态出现过没有. 然而 储存答案. 需要一个桶?或者sort咯 不过多个cnt 我咧懒得打. 所以我们用一个\(vis[N][N][N] ;\) 来判重 表示这种状态出现过没有 出现过就直接返回. 然后用一个ans数组来储存答案\(ans[N] ;\) 都是布尔型的就行. 然后进入程序片段. 一共三个字母 则倒法有 \(3!=1*2*3=6\). 那就手工模拟好了.不用循环了