/**
一个队列cup[1000]
先让初始化的三个数进入队列。
然后出列一个,这个时候三个杯水量不同,
在这个基础上,按照不同的倒法倒一次水,并让倒后的状态进入队列,
这样不停地倒,直到有一个杯中的水是所有水的一半;或者所有的状态都被存到了队列中,即失败了
*/
#include<iostream>
using namespace std;
struct Cup //存储倒水过程中的状态
{
public:
Cup():cupa(0),cupb(0),cupc(0),father(-1){}
Cup(int a,int b,int c,int f):cupa(a),cupb(b),cupc(c),father(f){}
int cupa;
int cupb;
int cupc;
int father;
};
class divide
{
public:
divide(int aa,int bb,int cc);
void doDivide();
bool isOver();
bool isContain(const Cup &pp);
void print();
bool atob();//从a倒到b
bool atoc();//从a倒到c
bool btoc();//从b倒到c
bool btoa();//从b倒到a
bool ctob();//从c倒到b
bool ctoa();//从c倒到a
private:
struct Cup p;
int a;
int b;
int c;
Cup cup[1000];
void push(const Cup&p);
int count;
int first;
};
divide::divide(int aa,int bb,int cc):a(aa),b(0),c(0),count(0),first(0)
{
p.cupa = a;
p.cupb = bb;
p.cupc = cc;
p.father= -1;
push(p);
}
void divide::push(const Cup&p)
{
if(count>1000)
{
cout<<"堆栈溢出\n";
return;
}
else
cup[count++] = p;
}
void divide::doDivide()
{
int f =0;
while(first<count&&!isOver())
{
if(first!=0) //表示不是第一次倒水
{
a = cup[first].cupa;
b = cup[first].cupb;
c = cup[first].cupc;
}
if(atob()|atoc()|btoc()|btoa()|ctoa()|ctob())
{
f = 1;
first ++;
}
else
{
f=0;
break;
}
}
if(f==0)
cout<<"不能完成均分\n";
else
print();
}
bool divide::isOver()
{
if(a==p.cupa/2||b==p.cupa/2||c==p.cupa/2)
return true;
return false;
}
bool divide::isContain(const Cup& pp)
{
for(int i=0;i<count;i++)
{
if(pp.cupa==cup[i].cupa&&pp.cupb==cup[i].cupb&&pp.cupc==cup[i].cupc)
return true;
}
return false;
}
bool divide::atob()
{
int tempa,tempb,tempc;
if(a>0&&b<p.cupb)
{
if(a>(p.cupb-b)) //b中容纳不下a中剩余的水
{
tempa = a-(p.cupb-b);
tempb = p.cupb;
tempc = c;
}
else//b能够容纳a中剩余的水
{
tempa = 0;
tempb = b + a;
tempc = c;
}
struct Cup tempp(tempa,tempb,tempc,first);
if(!isContain(tempp)) //如果队列中没有
{
push(tempp);
return true;
}
return false;
}
}
bool divide::atoc()
{
int tempa,tempb,tempc;
if(a>0&&c<p.cupc)
{
if(a>(p.cupc-c)) //c中容纳不下a中剩余的水
{
tempa = a-(p.cupc-c);
tempb = b;
tempc = p.cupc;
}
else//c能够容纳a中剩余的水
{
tempa = 0;
tempb = b;
tempc = c + a;
}
struct Cup tempp(tempa,tempb,tempc,first);
if(!isContain(tempp)) //如果队列中没有
{
push(tempp);
return true;
}
return false;
}
}
bool divide::btoc()
{
int tempa,tempb,tempc;
if(b>0&&c<p.cupc)
{
if(b>(p.cupc-c)) //c中容纳不下b中剩余的水
{
tempa = a;
tempb = b-(p.cupc-c);
tempc = p.cupc;
}
else//c能够容纳b中剩余的水
{
tempa = a;
tempb = 0;
tempc = c+b;
}
struct Cup tempp(tempa,tempb,tempc,first);
if(!isContain(tempp)) //如果队列中没有
{
push(tempp);
return true;
}
return false;
}
}
bool divide::btoa()
{
int tempa,tempb,tempc;
if(b>0&&a<p.cupa)
{
tempa = a+b;
tempb = 0;
tempc = c;
struct Cup tempp(tempa,tempb,tempc,first);
if(!isContain(tempp)) //如果队列中没有
{
push(tempp);
return true;
}
return false;
}
}
bool divide::ctoa()
{
int tempa,tempb,tempc;
if(c>0&&a<p.cupa)
{
tempa = a+c;
tempb = b;
tempc = 0;
struct Cup tempp(tempa,tempb,tempc,first);
if(!isContain(tempp)) //如果队列中没有
{
push(tempp);
return true;
}
return false;
}
}
bool divide::ctob()
{
int tempa,tempb,tempc;
if(c>0&&b<p.cupb)
{
if(c>(p.cupb-b)) //b中容纳不下c中剩余的水
{
tempa = a;
tempb = p.cupb;
tempc = c-(p.cupb-b);
}
else//b能够容纳c中剩余的水
{
tempa = a;
tempb = b+c;
tempc = 0;
}
struct Cup tempp(tempa,tempb,tempc,first);
if(!isContain(tempp)) //如果队列中没有
{
push(tempp);
return true;
}
return false;
}
}
void divide::print()
{
Cup temp_cup[count];
int temp_count = 0;
int i;
for(i = count-1;cup[i].father!=-1;i=cup[i].father)
temp_cup[temp_count++] = cup[i];
cout<<"a "<<"b "<<"c "<<'\n';
for(i= temp_count-1;i>=0;i--)
cout<<temp_cup[i].cupa<<" "<<temp_cup[i].cupb<<" "<<temp_cup[i].cupc<<'\n';
}
main(void)
{
divide d1(12,7,5),d2(16,9,7),d3(8,5,3),d4(10,6,4);
d1.doDivide();
d2.doDivide();
d3.doDivide();
d4.doDivide();
}