USACO-Section1.4 Mother's Milk【广度优先搜索】

题目描述:

农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的。有时,农民把牛奶从一个桶倒到 另一个桶中,直到被灌桶装满或原桶空了。当然每一次灌注都是完全的。由于节约, 牛奶不会有丢失
写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。(翻译来源:NOCOW

INPUT FORMAT:

单独的一行包括三个整数A,B和C。

OUTPUT FORMAT:

只有一行,升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性


SAMPLE INPUT 1

8 9 10


SAMPLE OUTPUT 1

1 2 8 9 10


SAMPLE INPUT 2

2 5 10


SAMPLE OUTPUT 2

5 6 7 8 9 10


解题思路:
这道题的中心思想就是广度优先遍历,从初状态开始,尝试a->b,a->c,b->a,b->c,c->a,c->b;如果状态已经经历过了,则返回。下面是代码。

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
int a,b,c,v[20][20][20],ans[20];//v数组记录状态,ans数组记录结果
int min(int a,int b){
    return a<b?a:b;
}
void judge(int ta,int tb,int tc){
    if(v[ta][tb][tc])return ;//如果该状态已被标记,则return
    else{
        v[ta][tb][tc]=1;
        if(ta==0&&ans[tc]==0)ans[tc]=1;//如果a桶没有牛奶,则标记结果
        if(ta!=0&&tb<b)//a->b
        judge(ta-min(ta,b-tb),tb+min(ta,b-tb),tc);
        if(ta!=0&&tc<c)//a->c
        judge(ta-min(ta,c-tc),tb,tc+min(ta,c-tc));
        if(tb!=0&&ta<a)//b->a
        judge(ta+min(tb,a-ta),tb-min(tb,a-ta),tc);
        if(tb!=0&&tc<c)//b->c
        judge(ta,tb-min(tb,c-tc),tc+min(tb,c-tc));
        if(tc!=0&&ta<a)//c->a
        judge(ta+min(tc,a-ta),tb,tc-min(tc,a-ta));
        if(tc!=0&&tb<b)//c->b
        judge(ta,tb+min(tc,b-tb),tc-min(tc,b-tb));
    }
}
int main() {
    FILE *fin  = fopen ("milk3.in", "r");
    FILE *fout = fopen ("milk3.out", "w");
    fscanf(fin,"%d %d %d",&a,&b,&c);
    int i,j;
    judge(0,0,c);
    for(i=0;i<c;i++)
    if(ans[i])//由于c桶牛奶在初始状态下最多,所以以初始状态c桶牛奶数作为输出结尾
    fprintf(fout,"%d ",i);
    fprintf(fout,"%d\n",c);
    exit(0);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值