题目大意:有2个杯子(刚开始的时候是空的),容量为a,b。求通过以下三种操作判断能否使得出现为c升的水,如果可以的话,求最短的步骤数
1、drop 给1或者2倒光水
2、fill 给1或者2倒满水
3、pour 1 to 2 或者 pour 2 to 1
每次操作只能对一个杯子进行操作
思路:bfs,至于保存路径的话,也容易实现,因为对于每一个状态,其路径都是不同的,所以大可以把路径作为状态的一个属性。
AC Program:
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<iomanip>
#include<string>
#include<stdio.h>
#include<queue>
using namespace std;
int u,v,w;
int flag[103][103];
//每瓶水最多容量为100,利用此数组来标记访问过的状态
struct node
{
int a,b;
string r;
}tmp,ans;
void bfs()
{
queue<node>que;
memset(flag,0,sizeof(flag));
ans.a=0,ans.b=0,ans.r="";
//把每个状态的路径作为此状态的一个属性
que.push(ans);
flag[0][0]=1;
while(!que.empty())
{
tmp=que.front();
que.pop();
if(tmp.a==w || tmp.b==w)//找到目标,准备输出
{
//通过BFS的往外扩展出来的路径一定是最短的
//output!!!
string kg=tmp.r;
int len=kg.length();
cout<<len<<endl;
for(int i=0;i<len;i++)
{
switch(kg[i])
{
case '0': cout<<"DROP(1)"<<endl;break;
case '1': cout<<"DROP(2)"<<endl;break;
case '2': cout<<"FILL(1)"<<endl;break;
case '3': cout<<"FILL(2)"<<endl;break;
case '4': cout<<"POUR(1,2)"<<endl;break;
case '5': cout<<"POUR(2,1)"<<endl;break;
}
}
return;
}
for(int i=0;i<6;i++)//进行搜索
{
//利用swith是更简便的输出字符串
//6个入口,操作6次
switch(i)
{
case 0:{//操作:倒掉1
ans.a=0,ans.b=tmp.b,ans.r=tmp.r+"0";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;//标记
que.push(ans);
}
break;//注意了啦不要漏了
}
case 1:{//操作:倒掉2
ans.a=tmp.a,ans.b=0,ans.r=tmp.r+"1";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;
que.push(ans);
}
break;
}
case 2:{//操作:倒满1
ans.a=u, ans.b=tmp.b, ans.r=tmp.r+"2";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;
que.push(ans);
}
break;
}
case 3:{//操作:倒满2
ans.a=tmp.a, ans.b=v, ans.r=tmp.r+"3";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;
que.push(ans);
}
break;
}
case 4:{//操作:倒1给2
if(tmp.a>v-tmp.b)//注意是ans还是tmp
{
ans.a=tmp.a-(v-tmp.b) , ans.b=v, ans.r=tmp.r+"4";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;
que.push(ans);
}
}
else
{
ans.a=0 , ans.b=tmp.a+tmp.b, ans.r=tmp.r+"4";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;
que.push(ans);
}
}
break;
}
case 5:{//操作:倒2给1
if(u-tmp.a<tmp.b)
{
ans.a=u,ans.b=tmp.b-(u-tmp.a),ans.r=tmp.r+"5";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;
que.push(ans);
}
}
else
{
ans.a=tmp.a+tmp.b,ans.b=0,ans.r=tmp.r+"5";
if(!flag[ans.a][ans.b])
{
flag[ans.a][ans.b]=1;
que.push(ans);
}
}
break;
}
}
}
}
cout<<"impossible"<<endl;
}
int main()
{
cin>>u>>v>>w;
bfs();
//system("pause");
return 0;}