题目叙述:
倒水问题
“fill A” 表示倒满A杯,"empty A"表示倒空A杯,“pour A B” 表示把A的水倒到B杯并且把B杯倒满或A倒空。
Input
输入包含多组数据。每组数据输入 A, B, C
数据范围 0 < A <= B 、C <= B <=1000 、A和B互质。
Output
你的程序的输出将由一系列的指令组成。这些输出行将导致任何一个罐子正好包含C单位的水。每组数据的最后一行输出应该是“success”。输出行从第1列开始,不应该有空行或任何尾随空格。
Sample Input
2 7 5
2 7 4
Sample Output
fill B
pour B A
success
fill A
pour A B
fill A
pour A B
success
题目思路:
对当前杯子A,B的操作可以分为六种情况:
1、把A中的水倒空
2、把B中的水倒空
3、(A中不满)将A倒满水
4、(A中不满)将B中的水倒入A中(A是否倒满?)
5、(B中不满)将B中倒满水
6、(B中不满)将A中的水倒入B中(B是否倒满?)
利用bfs搜索,从(0,0)开始,直到其中一个杯子中水的体积等于C时停止。根据上述条件,将两个杯子可能的下一状态放入队列中,并利用map记录父节点与子节点,同时利用flag记录得到此时状态的条件,方便后续输出具体操作。
最后输出,利用递归实现具体操作的输出。
代码实现:
#include<iostream>
#include<queue>
#include<map>
using namespace std;
struct node
{
int x,y;
int flag;
bool operator<(const node &s) const
{
return x!=s.x ? x<s.x:y<s.y;
}
};
map<node, node> record;
queue<node> s;
void print(node p)
{
if(p.flag==1)
cout<<"empty A"<<endl;
else if(p.flag==2)
cout<<"empty B"<<endl;
else if(p.flag==3)
cout<<"fill A"<<endl;
else if(p.flag==4)
cout<<"pour B A"<<endl;
else if(p.flag==5)
cout<<"fill B"<<endl;
else if(p.flag==6)
cout<<"pour A B"<<endl;
}
void judge(node now,node nex)
{
if (record.find(nex) == record.end())
{
record[nex]=now;
s.push(nex);
}
}
void printff(node p)
{
if((p.x==0&&p.y==0)||(record.find(p)==record.end()))
{
print(p);
return;
}
printff(record[p]);
print(p);
}
void bfs(int A,int B,int C)
{
node z;
z.x=0;
z.y=0;
z.flag=0;
s.push(z);
while(!s.empty())
{
node now=s.front();
s.pop();
node nex;
if(now.x==C||now.y==C)
{
printff(now);
return;
}
if(now.x>0)
{
nex.x=0;
nex.y=now.y;
nex.flag=1;//把A的水倒空
judge(now,nex);
}
if(now.y>0)
{
nex.y=0;
nex.x=now.x;
nex.flag=2;//把B的水倒空
judge(now,nex);
}
if(now.x<A)
{
nex.x=A;
nex.y=now.y;
nex.flag=3;//给A加满
judge(now,nex);
if(now.y!=0)
{
if(now.x+now.y<=A)
{
nex.x=now.x+now.y;//把B的水倒入A中
nex.y=0;
nex.flag=4;
judge(now,nex);
}
else
{
nex.x=A;
nex.y=now.x+now.y-A;
nex.flag=4;
judge(now,nex);
}
}
}
if(now.y<B)
{
nex.y=B;
nex.x=now.x;
nex.flag=5;//B续满
judge(now,nex);
if(now.x!=0)
{
if(now.x+now.y<=B)
{
nex.y=now.x+now.y;
nex.x=0;
nex.flag=6;//把A中的水倒入B中
judge(now,nex);
}
else
{
nex.y=B;
nex.x=now.x+now.y-B;
nex.flag=6;
judge(now,nex);
}
}
}
}
}
int main()
{
int A,B,C;
while(cin>>A>>B>>C)
{
bfs(A,B,C);
cout<<"success"<<endl;
}
return 0;
}