注册 登录
编程论坛 C++教室

求助:10L的瓶子装满水,再给你一个3L,一个7L的瓶子,分出2个5L的水!

chen_study 发布于 2009-09-08 08:21, 4209 次点击
如题,手动分,我分得出来!
A为10L的瓶子,B为3L的瓶子,C为7L的瓶子:
A   B  C
10  0  0
3   0  7
3   3  4
6   0  4
6   3  1
9   0  1
9   1  0
2   1  7
2   3  5
5   0  5
这是手动倒得过程,用C++我想了半天不知道怎么写这个循环!
哪位大侠帮忙解决下!
不胜感激!
21 回复
#2
wqa0072009-09-08 10:40
能不能把你的要求说具体点?是不是要求三个变量先赋初值。然后写小段程序 最后输出三个变量的值。使变量值满足要求?
#3
chen_study2009-09-08 14:49
程序功能是,知道有3个瓶子,分别为10L 3L 7L
开始的时候,10L的装满水,3L和7L的空的.
最后的结果要分成2个5L,分别装入2个瓶子.
程序要求输出倒水的过程,过程中,各个瓶子中的水的量..
3个变量,为3个瓶子当前的水的量,,但每个变量又有界限!
我想弄个循环,就是弄不出来,帮帮忙!!
#4
chen_study2009-09-08 18:01
头绪是这样的
把3个瓶子由大到小从左到右排好



从左到右倒过去(单次倒水结束标志:倒出的瓶子空了或装进的瓶子满了)
循环至最右边的瓶子时,跳回至最左边的瓶子

整个循环的标志:3个瓶子中出现一个为5L的

整个程序最后一步:把另外2个瓶子里的果汁倒进一个瓶子中(容量大的那个)

伪代码我自己写出来,我自己都看不大明白

我是这样分析的,可我不知道怎么用C++代码来实现这个循环
谁帮忙处理下,我都搞了好久了!晕啊
#5
kqscy12009-09-08 18:14
会VC++么,MFC会的话可以写;定义4个变量3个代表3个瓶子,1个就作为临时存水用。做3个注入水的菜单,和3个抽取水的菜单。然后根据代表3个瓶子的变量画出瓶子当前的状态
#6
sunkaidong2009-09-08 20:02
三个数按照一定的规律相加为10,只要有一个数为5就结束。。呵呵
#7
BlueGuy2009-09-08 20:13
回复 6楼 sunkaidong
???
#8
xufen3402009-09-08 22:18
这道题里有个规律:

 
第一步:当中间数b为0,就要使这三个数中间为3,把最后一个数c分最大给b。如果最后一个数c不够,就要
就要用第一个数a来最大补给最后一个数c,然后最后一个数c再给第二个数b.
 
第二步:当中间数b为3,就要使这三个数中间一个为0,把b付给a,察看两边a,c相等,不等继续循环第一步.
 
第一次:
3 0 7 假如a!=c;为了使中间数b不为0,只有c->b,结果3,3,4(if(b=0&&c>b) b=3;c=c-3;)
                                                     为何这里写c>b请看第五次
第二次:
3 3 4  当中间数b不为0,只有b->a,结果6,0,4  察看两边a,c相等,不等就(if(b!=0) a=a+3;b=0;)
第三次:
6 0 4  假如a!=c;为了使中间数b不为0,只有c->b,只有6,3,1(if(b=0&&c>b) b=3;c=c-3;)
第四次:
6 3 1  当中间数b不为0,只有b->a,结果9,0,1 察看两边a,c相等,不等就(if(b!=0) a=a+3;b=0;)
第五次:
9 0 1 当中间数b不为0,只有c->b,但是c全给了b后c为0了,a就要补足c.
                               结果:2,1,7(if(b=0&&c<=b) b=c;c=7;a-=7;)
 
第六次:
2 1 7 这时候,c被a补足了后继续补给b让b=3.
第七次:
2 3 5  当中间数b不为0,只有b->a,结果5,0,5  察看两边a,c相等,最后a,c平衡.
 
 
 
这3个数字好像告诉我们,2个人平分一笔钱,但两个人都不知道对方有多少钱,
请第三个人来做公证人,把钱给平分了.当然第三个人每次拿到的钱都小于2家原有的钱,
然后分阿分得,就平了.
#9
xufen3402009-09-08 22:51
写的太快,有个地方错了,现在更正。
第一次:  
3 0 7 假如a!=c;为了使中间数b不为0,只有c->b,结果3,3,4(if(b=0&&c>3) b=3;c=c-3;)  // 这里3是因为中间瓶子为3L
                                                     为何这里写c>b请看第五次  
第二次:  
3 3 4  当中间数b不为0,只有b->a,结果6,0,4  察看两边a,c相等,不等就(if(b!=0) a=a+3;b=0;)  
第三次:  
6 0 4  假如a!=c;为了使中间数b不为0,只有c->b,只有6,3,1(if(b=0&&c>3) b=3;c=c-3;)  
第四次:  
6 3 1  当中间数b不为0,只有b->a,结果9,0,1 察看两边a,c相等,不等就(if(b!=0) a=a+3;b=0;)  
第五次:  
9 0 1 当中间数b不为0,只有c->b,但是c全给了b后c为0了,a就要补足c.  
                               结果:2,1,7(if(b=0&&c<=3) b=c;c=7;a-=7;)  
 
第六次:  
2 1 7 这时候,c被a补足了后继续补给b让b=3.  
第七次:  
2 3 5  当中间数b不为0,只有b->a,结果5,0,5  察看两边a,c相等,最后a,c平衡.  
#10
chen_study2009-09-09 08:47
条件控制我看明白了,,谢谢

现在还一个问题想请教下,这个变量定义跟初始化要怎么弄呢,

初始化我觉得是按题目给的初始化为 10 0 0


不过他们又有上限,我不知道怎么控制定义

麻烦了!


#11
xufen3402009-09-09 09:40
初始化随便阿,
定义三变量代表三个瓶体积  
avolume,bvolume,cvolume
定义三变量代表三个瓶里的水
awater,bwater,cwater
如果你取2个瓶子,一个瓶子装满水a,一个不装水c,
所以
cin>>avolume>>cvolume;//选2个瓶子
awater=avolume;//a瓶子装满水。
1.如果avolume==cvolume,直接选取一个bvolume=avolume/2;一步完成。
//上面一段话就是如果2个瓶子一样,选取一个b瓶子体积为a瓶子一半就可以。
2.如果a!=b
就取一个中间瓶,
cin>>bvolume;
这个中间瓶一定要bvolume<=avolume-cvolume,否则重新
cin>>b;这里如果avolume>bvolume,我们按照上面的来,如果
avolume<bvolume,就要调换下,总要满足avolume>bvolume.

三个瓶体积选好了,a瓶子也装满水了(awater=avolume)。

就按照我上面的循环,开始改变了,每次cout<<awater,bwater,cwater;
#12
chen_study2009-09-09 11:59
感谢了,我去写一下代码,有不懂的地方,麻烦你再帮我解决下!
呵呵
#13
大爱无言FF2009-09-09 13:37
不知道大家有没有发现一个规律,那就是:每次分水时要么把原瓶子里的水全部倒光,要么把另一个瓶子装满!我想把这个问题搞清楚应该我助于解决问题吧!
#14
chen_study2009-09-09 14:19
还是写不出来啊,循环控制条件怎么搞都搞不对,,,


好晕哪!
#15
chen_study2009-09-09 14:51
帮我看下这个代码

#include <iostream>
using namespace std;
 
class Bottel
{
public:
    Bottel(int capacity);
     
public:
    void FlowOut(Bottel* odj);
    int FlowIn(int Mete);
    int getMete();
    void Full();
     
private:
    int maxCapa;
    int theMete;
};
 
 
 
Bottel::Bottel(int capacity)
:maxCapa(capacity)
,theMete(0)
{
     
}
 
void Bottel::Full()
{
    theMete = maxCapa;
}
 
int Bottel::getMete()
{
    return theMete;
}
 
void Bottel::FlowOut(Bottel* obj)
{
    theMete = obj->FlowIn(theMete);
}
 
int Bottel::FlowIn(int Mete)
{
    if(theMete + Mete <= maxCapa)
    {
        theMete = theMete + Mete;
        return 0;
    }
    else
    {
        int Return = theMete + Mete - maxCapa;
        theMete = maxCapa;
        return Return;
    }
}
 
 
int main()
{
    Bottel* BArr[3];  
    BArr[0] = new Bottel(7);
    BArr[1] = new Bottel(3);
    BArr[2] = new Bottel(10);
     
    BArr[2]->Full();
     
    int i = 0;
    int tenMete = 0;
    int sevMete = 0;
     
    while(tenMete!=5)
    {
        if(sevMete!=5)
        {
            BArr[2]->FlowOut(BArr[0]);
            sevMete = BArr[0]->getMete();
        }
        else
        {
            BArr[1]->FlowOut(BArr[2]);
            tenMete = BArr[2]->getMete();
        }
         
        i = 0;
         
        while(sevMete!=0 && sevMete!=5)
        {
            BArr[i]->FlowOut(BArr[i+1]);
            tenMete = BArr[2]->getMete();
            sevMete = BArr[0]->getMete();
            
            i=(i+1)%2;
        }
         
         
    }
     
     
    return 0;
}
#16
xufen3402009-09-09 16:40

//你先看看这个
#include<iostream>
using namespace std;
void movewater(int const& avolume,int const& bwater,int const& cvolume);
int main()
{
    int avolume,bvolume,cvolume;
    //输入2个a,c瓶子体积
    cin>>avolume>>cvolume;
    if(avolume==cvolume){        
        //留给你了写了         
    }else{
        //a瓶体积小于c瓶,2个标签换过来。
        //要保持a瓶体积大于c瓶.
        if(avolume<cvolume){
            int tmpvolume;
            tmpvolume=avolume;
            avolume=cvolume;
            cvolume=tmpvolume;
        }
        //输入b瓶子体积,第三个数要保证(a-b)/2=整数,否则死循环,交给你了。
        cin>>bvolume;
        movewater(avolume,bvolume,cvolume);
    }
     
}
 
void movewater(int const& avolume,int const& bvolume,int const& cvolume)
{
    int awater,bwater,cwater;
    //a瓶子装满水,b,c等待装水。
    awater=avolume;     
    bwater=0;
    cwater=0;
    //循环倒水
    while(awater!=cwater){
        //如果c瓶为空,则a倒入c         
        if((cwater==0)){
            cwater=cvolume;
            awater=awater-cvolume;
            cout<<awater<<","<<bwater<<","<<cwater<<","<<endl;
        }
 
        //如果b瓶为空,则c倒入b
        else if(bwater==0){
            //b瓶的水和c瓶的水比较后倒入
            if(cwater>=bvolume){
                cwater=cwater-bvolume;
                bwater=bvolume;
            }else{
                bwater=cwater;
                cwater=0;               
            }
            cout<<awater<<","<<bwater<<","<<cwater<<","<<endl;
        }
        //如果b瓶为满,则b倒入a
        else if(bwater==bvolume){
            awater=awater+bwater;
            bwater=0;
            cout<<awater<<","<<bwater<<","<<cwater<<","<<endl;
        }
        //如果b瓶不满也不空,则c倒满b。
        else if(bwater<bvolume){
            cwater=cwater-(bvolume-bwater);
            bwater=bvolume;
            cout<<awater<<","<<bwater<<","<<cwater<<","<<endl;
        }
 
    }
}
 
#17
xufen3402009-09-09 16:56
输入b瓶子体积,第三个数要保证(a-b)/2=整数,否则死循环这个是我分析错误,选取b瓶子体积也是要考虑的。太忙,晚上想想。
#18
chen_study2009-09-09 18:07
这个我看明白了!!

不过输入瓶子的顺序必须是 10 7 3  
输入10 3 7或其他顺序就不可以

这个有办法解决吗??

不过这个程序经你这么一些一说明..........牛

是在是太感谢,,,,,


#19
xufen3402009-09-09 20:44
//改好了,现在随便你玩了,都可以平衡,死循环也会告诉你,这个程序就这样结束吧。

#include<iostream>  
using namespace std;  
void movewater(int const& avolume,int const& bwater,int const& cvolume);  
void move(int const& fromvolume ,int const& tovolume,int & fromwater,int & towater);
int main()  
{  
    int avolume,bvolume,cvolume;  
    //输入2个a,c瓶子体积  
    cin>>avolume>>bvolume>>cvolume;  
    movewater(avolume,bvolume,cvolume);     
}  
 
void movewater(int const& avolume,int const& bvolume,int const& cvolume)  
{  
    int awater,bwater,cwater;
    int i=1;
    //a瓶子装满水,b,c等待装水。  
    awater=avolume;      
    bwater=0;  
    cwater=0;  
    //循环倒水  
    while(awater!=cwater){  
        //如果c瓶为空,则a倒入c         
        if((cwater==0)){
        move(avolume,cvolume,awater,cwater);
        cout<<avolume<<"("<<awater<<")"<<",";
        cout<<bvolume<<"("<<bwater<<")"<<",";
        cout<<cvolume<<"("<<cwater<<")"<<endl;
        }
 
 
        //如果b瓶为空,则c倒入b  
        else if(bwater==0){  
           move(cvolume,bvolume,cwater,bwater);
           cout<<avolume<<"("<<awater<<")"<<",";
           cout<<bvolume<<"("<<bwater<<")"<<",";
           cout<<cvolume<<"("<<cwater<<")"<<endl;
        }  
        //如果b瓶为满,则b倒入a  
        else if(bwater==bvolume){  
            move(bvolume,avolume,bwater,awater);
            cout<<avolume<<"("<<awater<<")"<<",";
            cout<<bvolume<<"("<<bwater<<")"<<",";
            cout<<cvolume<<"("<<cwater<<")"<<endl;
        }  
        //如果b瓶不满也不空,则c倒满b。  
        else if(bwater<bvolume){  
            move(cvolume,bvolume,cwater,bwater);
            cout<<avolume<<"("<<awater<<")"<<",";
            cout<<bvolume<<"("<<bwater<<")"<<",";
            cout<<cvolume<<"("<<cwater<<")"<<endl;
        }  
        //如果和第一次重复了,那就不能达到平衡。
        int astate,bstate,cstate;
        if(i==1){
            astate=awater;
            bstate=bwater;
            cstate=cwater;
        }else{
            if((astate==awater)&&(bstate==bwater)&&(cstate==cwater)){
                cout<<"program go into dead"<<endl;
                break;
            }
        }
        i++;
 
    }  
}  
 
 
//倒入
void move(int const& fromvolume ,int const& tovolume,int & fromwater,int & towater)
{
    /*
    *第一个瓶子向第二个瓶子最大限度倒入
    */
 
    if(fromwater>=(tovolume-towater)){
        fromwater=fromwater-(tovolume-towater);
        towater=tovolume;
    }else{
        towater=towater+fromwater;
        fromwater=0;
    }
}
#20
RongDQ2009-09-11 16:04
用递归不用循环
看这样分析怎样?
3个瓶子的水量用数组表示。
每一次倒水用一种变换来表示,变换的结果,是数组的改变。
比如第一次
//////////////////////
10L   3L    7L
/////////////////////
10    0     0
对这个状态,可以进行6种操作:10倒进3,10倒进7,3倒进10,3倒进7,7倒进10,7倒进3
但因每次到过之后必定有一个满杯子或空杯子,所以相应的理论上只有4种操作。对应4种计算。

那么10   0    0下面就有4个节点(理论上),而且每个节点又有4个分节点。
这个树到第10层,就有4^10个节点。这个数不太大。用递归时间上应该没问题。

关于数据的选择,不知道用16进制的百位数表示是否更快?百位表第一个杯子,十位表第二个,个位表示第三个。

如果有一天,一个机器人看到这个问题,编了个程序解决了,会是什么结果呢?
也许机器人离选举权就不远了。
#21
yxb00012009-09-14 15:34
#include<iostream>
using namespace std;
 
void main()
{
    int sa,sb,sc; //sa,sb,sc分别表a,b,c瓶子实际盛水量
    int la=10,lb=3,lc=7,sum=10; //la,lb,lc表各瓶子的容量,sum表水的总量。
    sa=sum;
    sb=0;
    sc=0;
    while(sc<lc)
    {
        sc++;
 
    }
    cout<<"sa="<<(sa-sc)<<",sb="<<sb<<",sc="<<sc<<"\n";
    sa=sa-sc;
    do{sb++;}while(sb<lb);
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<(sc-sb)<<"\n";
    sc=sc-sb;
    if(sb==lb)
    {
        sa=sa+sb;
        sb=sb-lb;
    }
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<sc<<"\n";
    while(sb<lb){sb++;};
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<(sc-sb)<<"\n";
    sc=sc-sb;
    if(sb==lb)
    {
        sa=sa+sb;
        sb=sb-lb;
    }
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<sc<<"\n";
    if(sb==0)
    {
        sb=sb+sc;
        sc=sc-sc;
    }
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<sc<<"\n";
    while(sc<lc)
    {sc++;}
    sa=sa-sc;
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<sc<<"\n";
    while(sb!=lb)
    {
        sb++;
        sc--;
    }
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<sc<<"\n";
    while(sb!=0)
    {
        sb--;
        sa++;
    }
    cout<<"sa="<<sa<<",sb="<<sb<<",sc="<<sc<<"\n";
 
}
#22
DreamerLJX2015-10-26 19:32
刚才楼上有人说定义四个变量,三个代表瓶子,一个作为临时存水的瓶子,那么这个临时存水瓶子的容积该怎么计算呢?
1