USCAO-Section 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.

题意:
有ABC三个容器,其容积不同但都小于等于20;一开始C是满的,可进行的操作有两种:1、将一个容器的牛奶全部倒入另一个容器(另一个容器可以承受)2、将一个容器的牛奶倒入另一个容器直到那个容器满了

求在进行操作后,C中所剩的牛奶的数量的可取值,全部从小到大输出。

题解:
首先想到的就是模拟六种操作 a->b a->c,b->a b->c,c->a c->b;每种都有两种情况,一个是自己倒空,一个是将对方倒满,使用深度搜索模拟倒的情况,在每一次递归前判断三个容器中各自的牛奶量的情况是否已经出现过,出现过就return;没有就判断C容器的量是否出现过,没有就加入记录,然后继续往下模拟操作。

代码如下:

/*
ID:newyear111
PROG: milk3
LANG: C++
*/

#include <iostream>
#include <fstream>
#include <string>
#include<algorithm>
using namespace std;
const int N=25;
int vis[N][N][N];//记录ABC的状态以去重
int ans[N];//记录答案
int A,B,C; 

void dfs(int a,int b,int c){
    if(vis[a][b][c]) return;
    vis[a][b][c]=1;
    if(!a&&!ans[c])
    {
        ans[c]=1;   
    }   
    //模拟六种情况
    //a->b
    if(a>=B-b) dfs(a-B+b,B,c);
    else dfs(0,a+b,c);
    //a->c
    if(a>=C-c) dfs(a-C+c,b,C);
    else dfs(0,b,c+a);
    //b->a
    if(b>=A-a) dfs(A,b-A+a,c);
    else dfs(a+b,0,c); 
    //b->c
    if(b>=C-c) dfs(a,b-C+c,C);
    else dfs(a,0,b+c);
    //c->a
    if(c>=A-a) dfs(A,b,c-A+a);
    else dfs(a+c,b,0);
    //c->b 
    if(c>=B-b) dfs(a,B,c-B+b);
    else dfs(a,c+b,0);
} 

int main()
{
    ifstream fin("milk3.in");
    ofstream fout("milk3.out");
    fin>>A>>B>>C;
    dfs(0,0,C);
    for(int i=0;i<C;i++){
        if(ans[i])
            fout<<i<<" ";   
    }
    fout<<C<<endl;
    fin.close();
    fout.close();
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值