NYOJ-21-三个水杯

来源:互联网 发布:想加盟淘宝网店 编辑:程序博客网 时间:2024/04/30 04:50

描述
给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子。三个水杯之间相互倒水,并且水杯没有标识,只能根据给出的水杯体积来计算。现在要求你写出一个程序,使其输出使初始状态到达目标状态的最少次数。

输入
第一行一个整数N(0< N <50)表示N组测试数据
接下来每组测试数据有两行,第一行给出三个整数V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三个水杯的体积。
第二行给出三个整数E1 E2 E3 (体积小于等于相应水杯体积)表示我们需要的最终状态

输出
每行输出相应测试数据最少的倒水次数。如果达不到目标状态输出-1

样例输入
2
6 3 1
4 1 1
9 3 2
7 1 1

样例输出
3
-1

这是一道经典的bfs,虽然代码篇幅很长,但是原理很简单,也容易理解。

#include <stdio.h>typedef struct State{    int Ei;    int Ej;    int Ek;    int Step;} State;State S[5050];int V1, V2, V3;int E1, E2, E3;int head, tail;void init(){    S[0].Ei = V1;    S[0].Ej = 0;    S[0].Ek = 0;    S[0].Step = 0;    head = 0;    tail = 1;}int haveSame(){    int i;    for (i = 0; i < tail; i++)    {        if (S[i].Ei == S[tail].Ei && S[i].Ej == S[tail].Ej && S[i].Ek == S[tail].Ek)        {            return 1;        }    }    return 0;}int judge(int Ei, int Ej, int Ek, int Step){    if (Ei == E1 && Ej == E2 && Ek == E3)    {        printf("%d\n", Step);        return 1;    }    return 0;}//BFSvoid solve(){    if (judge(S[0].Ei, S[0].Ej, S[0].Ek, S[0].Step))    {        return ;    }    while (head < tail)    {        if (S[head].Ei > 0)        {            //第一个杯子往第二个杯子里倒            if (S[head].Ej < V2)            {                S[tail].Ek = S[head].Ek;                S[tail].Ej = S[head].Ei > V2 - S[head].Ej ? V2 : S[head].Ei + S[head].Ej;                S[tail].Ei = S[head].Ei > V2 - S[head].Ej ? S[head].Ei - V2 + S[head].Ej : 0;                S[tail].Step = S[head].Step + 1;                if (judge(S[tail].Ei, S[tail].Ej, S[tail].Ek, S[tail].Step))                {                    return ;                }                if (!haveSame())                {                    tail++;                }            }            //第一个杯子往第三个杯子里倒            if (S[head].Ek < V3)            {                S[tail].Ej = S[head].Ej;                S[tail].Ek = S[head].Ei > V3 - S[head].Ek ? V3 : S[head].Ei + S[head].Ek;                S[tail].Ei = S[head].Ei > V3 - S[head].Ek ? S[head].Ei - V3 + S[head].Ek : 0;                S[tail].Step = S[head].Step + 1;                if (judge(S[tail].Ei, S[tail].Ej, S[tail].Ek, S[tail].Step))                {                    return ;                }                if (!haveSame())                {                    tail++;                }            }        }        if (S[head].Ej > 0)        {            //第二个杯子往第一个杯子里倒            if (S[head].Ei < V1)            {                S[tail].Ek = S[head].Ek;                S[tail].Ei = S[head].Ej > V1 - S[head].Ei ? V1 : S[head].Ej + S[head].Ei;                S[tail].Ej = S[head].Ej > V1 - S[head].Ei ? S[head].Ej - V1 + S[head].Ei : 0;                S[tail].Step = S[head].Step + 1;                if (judge(S[tail].Ei, S[tail].Ej, S[tail].Ek, S[tail].Step))                {                    return ;                }                if (!haveSame())                {                    tail++;                }            }            //第二个杯子往第三个杯子里倒            if (S[head].Ek < V3)            {                S[tail].Ei = S[head].Ei;                S[tail].Ek = S[head].Ej > V3 - S[head].Ek ? V3 : S[head].Ej + S[head].Ek;                S[tail].Ej = S[head].Ej > V3 - S[head].Ek ? S[head].Ej - V3 + S[head].Ek : 0;                S[tail].Step = S[head].Step + 1;                if (judge(S[tail].Ei, S[tail].Ej, S[tail].Ek, S[tail].Step))                {                    return ;                }                if (!haveSame())                {                    tail++;                }            }        }        if (S[head].Ek > 0)        {            //第三个杯子往第一个杯子里倒            if (S[head].Ei < V1)            {                S[tail].Ej = S[head].Ej;                S[tail].Ei = S[head].Ek > V1 - S[head].Ei ? V1 : S[head].Ek + S[head].Ei;                S[tail].Ek = S[head].Ek > V1 - S[head].Ei ? S[head].Ek - V1 + S[head].Ei : 0;                S[tail].Step = S[head].Step + 1;                if (judge(S[tail].Ei, S[tail].Ej, S[tail].Ek, S[tail].Step))                {                    return ;                }                if (!haveSame())                {                    tail++;                }            }//第三个杯子往第二个杯子里倒            if (S[head].Ej < V2)            {                S[tail].Ei = S[head].Ei;                S[tail].Ej = S[head].Ek > V2 - S[head].Ej ? V2 : S[head].Ek + S[head].Ej;                S[tail].Ek = S[head].Ek > V2 - S[head].Ej ? S[head].Ek - V2 + S[head].Ej : 0;                S[tail].Step = S[head].Step + 1;                if (judge(S[tail].Ei, S[tail].Ej, S[tail].Ek, S[tail].Step))                {                    return ;                }                if (!haveSame())                {                    tail++;                }            }        }        head++;    }    printf("-1\n");    return ;}int main(){    int N;    scanf("%d", &N);    while (N--)    {        scanf("%d %d %d", &V1, &V2, &V3);        scanf("%d %d %d", &E1, &E2, &E3);        init();        solve();    }    return 0;}

最开始写这个代码时,因为忽略了一种情况,而WA了两遍。
比如说,
9 7 5
9 0 0

这需要倒的次数为0,直接进行初始条件的判断后即可输出结果为0,然而因为我缺乏对初始条件的判断,所以导致结果为2,有些可悲,一失足成千古恨。当然,加上这个初始条件的判断后,顺利AC了……

0 0