Mother's Milk_usaco1.4_bfs

Mother’s Milk

Description

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.

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.

ANALYSIS

讲一下题目大意吧:
有三个桶ABC有各自的容量,C桶一开始装满了牛奶
请问经过若干次不流失不蒸发的倾倒后A桶为空的情况下C桶有哪些可能

这个专题好象就是搜索的,然后也似乎做过类似的题目

bfs寻找各种状态,有6种新途径:
1. a->b
2. a->c
3. b->c
4. b->a
5. c->b
6. c->a

枚举、判重、入队就好,这种题目做不出来简直了噜

输出最后不能有空格

CODE

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

#include <stdio.h>
#include <queue>
using namespace std;

struct milk
{
    int a,b,c;
};

queue<milk>q;
priority_queue<int>ans;

bool f[21][21],t[21];

int max(int x,int y)
{
    return x<y?y:x;
}

int min(int x,int y)
{
    return x<y?x:y;
}

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

    milk st;
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    st.a=0;
    st.b=0;
    st.c=c;
    q.push(st);

    while (q.size())
    {
        milk s,now=q.front();
        q.pop();
        if (now.a>=0&&now.b>=0&&now.c>=0)
        {
            f[now.a][now.b]=true;

            if (!now.a&&!t[now.c])
            {
                ans.push(-now.c);
                t[now.c]=true;
            }

            s=now;

            now.a=max(0,now.a+now.b-b);
            now.b=min(s.a+now.b,b);
            if (!f[now.a][now.b])
                q.push(now);

            now=s;
            now.a=max(0,now.a+now.c-c);
            now.c=min(s.a+now.c,c);
            if (!f[now.a][now.b])
                q.push(now);

            now=s;
            now.b=max(0,now.b+now.a-a);
            now.a=min(s.b+now.a,a);
            if (!f[now.a][now.b])
                q.push(now);    

            now=s;
            now.b=max(0,now.b+now.c-c);
            now.c=min(s.b+now.c,c);
            if (!f[now.a][now.b])
                q.push(now);

            now=s;
            now.c=max(0,now.c+now.b-b);
            now.b=min(s.c+now.b,b);
            if (!f[now.a][now.b])
                q.push(now);

            now=s;
            now.c=max(0,now.c+now.a-a);
            now.a=min(s.c+now.a,a);
            if (!f[now.a][now.b])
                q.push(now);                
        }
    }

    while (ans.size()>1)
    {
        printf("%d ",-ans.top());
        ans.pop();
    }
    printf("%d\n",-ans.top());

    fclose(stdin);
    fclose(stdout);
    return 0;
}

转载于:https://www.cnblogs.com/olahiuj/p/5781228.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值