Pour Water
倒水问题 “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
2 7 5
2 7 4
我的思路:
这道题我是利用BFS解决的。首先要分析出可能会发生的集中情况。
1.将A注满
2.B倒入A
3.将B注满
4.A导入B
5.清空A
6.清空B
针对六种情况,来进行宽度优先搜索。同时,也要在搜索时,记录当前节点的前一个节点,以至于在最后输出的时候,可以一句这个记录,来进行路径的输出。
我的代码:
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<string>
using namespace std;
struct Sta
{
int a,b;
bool operator <(const Sta &s)const
{
return a!=s.a?a<s.a:b<s.b;
}
};
int a,b,c;
map<Sta,Sta> from;
queue<Sta> Q;
void refresh(Sta &ai,Sta &bi)
{
if(from.find(bi)==from.end())
{
from[bi]=ai;
Q.push(bi);
}
}
void print(Sta &ans,int a,int b,int c)
{
if(ans.a!=0||ans.b!=0)
{
print(from[ans],a,b,c);
}//cout<<ans.a<<" "<<ans.b<<endl;
if(ans.a==0&&ans.b==0) return;
if(from[ans].a>0&&ans.a==0&&from[ans].b==ans.b) {
cout<<"empty A"<<endl;return;}
if(from[ans].b>0&&ans.b==0&&from[ans].a==ans.a) {
cout<<"empty B"<<endl;return;}
if(from[ans].a<ans.a)
{
if(from[ans].b!=0&&from[ans].b>ans.b) cout<<"pour B A"<<endl;
else cout<<"fill A"<<endl;
return;
}
if(from[ans].b<ans.b)if(from[ans].a>0&&ans.a==0&&from[ans].b==ans.b) cout<<"empty A"<<endl;
{
if(from[ans].a!=0&&from[ans].a>ans.a) cout<<"pour A B"<<endl;
else cout<<"fill B"<<endl;
return;
}
return;
}
void pour(int a,int b,int c)
{
Sta ss;
ss.a=0;
ss.b=0;
Q.push(ss);
while(!Q.empty())
{
Sta sl;
ss=Q.front();
Q.pop();
if(ss.a==c||ss.b==c)
{
print(ss,a,b,c);
cout<<"success"<<endl;
return;
}
if(ss.a>0)
{
sl.a=0;
sl.b=ss.b;
refresh(ss,sl);
}
if(ss.b>0)
{
sl.b=0;
sl.a=ss.a;
refresh(ss,sl);
}
if(ss.a<a)
{
sl.a=a;
sl.b=ss.b;
refresh(ss,sl);
if(ss.b!=0)
{
if(ss.a+ss.b<=a)
{
sl.a=ss.a+ss.b;
sl.b=0;
}
else
{
sl.a=a;
sl.b=ss.b-a+ss.a;
}
refresh(ss,sl);
}
}
if(ss.b<b)
{
sl.b=b;
sl.a=ss.a;
refresh(ss,sl);
if(ss.a!=0)
{
if(ss.a+ss.b<=b)
{
sl.b=ss.a+ss.b;
sl.a=0;
}
else
{
sl.b=b;
sl.a=ss.a-b+ss.b;
}
refresh(ss,sl);
}
}
}
}
int main()
{
while(cin>>a>>b>>c)
pour(a,b,c);
return 0;
}