Pots POJ - 3414
题目地址:
传送门(vj)
小明给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作
FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);
DROP(i) 将第i个容器抽干
POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,
二是第i个容器里的水全部倒入j中,第i个容器为空)
现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程
#include<cmath>
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=9999+10;
struct cup
{
public:
int a,b;
vector<char> st;
cup(int a=0,int b=0):a(a),b(b) {}
cup(const cup &t){
a=t.a;b=t.b;st=t.st;
}
bool operator == (const cup & t)const
{
if(a!=t.a&&b!=t.b)
return false;
return true;
}
bool operator != (const cup & t)const
{
if(a!=t.a&&b!=t.b)
return true;
return false;
}
};
int main()
{
// freopen("1.txt","r",stdin);
int a,b,c;
cin>>a>>b>>c;
int flag[150][150]= {0};
memset(flag,0,sizeof(flag));//不知道为啥,不加这一句就没有初始化成功,在这里卡了有一会,如果有知道的可以评论区滴滴一下,
cup be(0,0);
cup p=be,en(c,c);
queue<cup>qu;
qu.push(be);
flag[0][0]=1;
//
// 1 表示装满a
// 2 表示装满b
// 3 表示将a倒掉
// 4 表示将b倒掉
// 5 表示将a->b
// 6 表示将b->a
//
while(p.a!=c&&p.b!=c){
if(p.a<a) {//把a倒满
cup pp(p);
pp.a=a;
if(flag[a][pp.b]==0){
flag[a][pp.b]=1;
pp.st.push_back('1');
qu.push(pp);
}
}
if(p.b<b) {//把b倒满
cup pp(p);
pp.b=b;
if(flag[pp.a][b]==0){
flag[pp.a][b]=1;
pp.st.push_back('2');
qu.push(pp);
}
}
if(p.b>0) {//把b倒掉
cup pp(p);
pp.b=0;
if(flag[pp.a][0]==0)
{
flag[pp.a][0]=1;
pp.st.push_back('4');
qu.push(pp);
}
}
if(p.a>0) {//把a倒掉
cup pp(p);
pp.a=0;
if(flag[0][pp.b]==0)
{
flag[0][pp.b]=1;
pp.st.push_back('3');
qu.push(pp);
}
}
if(p.a>0&&p.b<b){ //a往b里倒
cup pp(p);
int l=b-pp.b;// b里面差的
if(pp.a<l){
pp.b+=pp.a;pp.a=0;
}
else{
pp.a-=(b-pp.b);pp.b=b;
}
if(flag[pp.a][pp.b]==0){
flag[pp.a][pp.b]=1;
pp.st.push_back('5');
qu.push(pp);
}
}
if(p.b>0&&p.a<a){//b往a里面倒
cup pp(p);
int l=a-pp.a;// a里面差的
if(pp.b<l){
pp.a+=pp.b;pp.b=0;
}
else{
pp.b-=(a-pp.a);pp.a=a;
}
if(flag[pp.a][pp.b]==0){
flag[pp.a][pp.b]=1;
pp.st.push_back('6');
qu.push(pp);
}
}
qu.pop();
if(qu.empty())break;
p=qu.front();
}
if(p==en){
int l=p.st.size();
cout<<l<<endl;
for(int i=0; i<l; i++){
switch(p.st[i]){
case '1' :cout<<"FILL(1)"<<endl;break;
case '2' :cout<<"FILL(2)"<<endl;break;
case '3' :cout<<"DROP(1)"<<endl;break;
case '4' :cout<<"DROP(2)"<<endl;break;
case '5' :cout<<"POUR(1,2)"<<endl;break;
case '6' :cout<<"POUR(2,1)"<<endl;break;
}
}
}
else
cout<<"impossible"<<endl;
}