题目大意:给出两个容量分别为V1,V2的瓶子,和目标水量C,瓶子可以进行如下3种操作:
(1)FILL( i ):将第i个瓶子装满水(i=1,2);
(2)DROP( i ):将第i个瓶子里的水全部到出(i=1,2);
(3)POUR( i,j):将第i个瓶子的水倒入第j个瓶子中(或将i中的水全部倒入j中,或将i中的一部分水倒入j中的时候j已经装满)。
现在问你经过多少次操作能使其中一个瓶子出现目标水量。如果不能实现,输出“impossible”。
实现代码如下:
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstring>
#include <string>
#include <map>
using namespace std;
int v1,v2;
int c;
int k1,k2;
int cmp1=0,cmp2=0;
int op[1000];
map <string,bool> vis;
typedef struct nod
{
int x,y;
int pos;
int step;
}node;
node que[1000];
string comb(int a,int b)
{
string s;
ostringstream os;
os<<a<<","<<b;
s=os.str();
os.str("");
return s;
}
void fill(int n,node cnt)
{
k1=cnt.x;
k2=cnt.y;
if(n==1) k1=v1;
else k2=v2;
string ts=comb(k1,k2);
if(!vis[ts])
{
vis[ts]=1;
que[cmp2].x=k1;
que[cmp2].y=k2;
que[cmp2].step=cnt.step+1;
que[cmp2].pos=cmp1;
if(n==1) op[cmp2++]=210;
else op[cmp2++]=220;
}
}
void drop(int n,node cnt)
{
k1=cnt.x;
k2=cnt.y;
if(n==1) k1=0;
else k2=0;
string ts=comb(k1,k2);
if(!vis[ts])
{
vis[ts]=1;
que[cmp2].x=k1;
que[cmp2].y=k2;
que[cmp2].step=cnt.step+1;
que[cmp2].pos=cmp1;
if(n==1) op[cmp2++]=110;
else op[cmp2++]=120;
}
}
void pour(int n,node cnt)
{
k1=cnt.x;
k2=cnt.y;
if(n==1)
{
if(k1+k2<=v2) { k2=k1+k2;k1=0; }
else { k1=k1+k2-v2; k2=v2; }
}
else
{
if(k1+k2<=v1) { k1=k1+k2; k2=0; }
else { k2=k1+k2-v1; k1=v1; }
}
string ts=comb(k1,k2);
if(!vis[ts])
{
vis[ts]=1;
que[cmp2].x=k1;
que[cmp2].y=k2;
que[cmp2].step=cnt.step+1;
que[cmp2].pos=cmp1;
if(n==1) op[cmp2++]=312;
else op[cmp2++]=321;
}
}
void bfs()
{
memset(op,0,sizeof(op));
vis.clear();
cmp1=0;cmp2=0;
que[cmp2].x=0;
que[cmp2].y=0;
que[cmp2++].step=0;
vis["0,0"]=1;
while(cmp1<cmp2)
{
node cnt=que[cmp1];
if(cnt.x==c||cnt.y==c)
{
printf("%d\n",cnt.step);
int cs=cnt.step;
int *steps=new int[cs+1];
steps[cs--]=cmp2-1;
while(cs)
{
steps[cs]=que[ steps[cs+1] ].pos;
cs--;
}
for(int i=1;i<=cnt.step;i++)
{
int tmp=op[ steps[i]-1 ];
switch(tmp/100)
{
case 1:printf("DROP(%d)\n",(tmp/10)%10);break;
case 2:printf("FILL(%d)\n",(tmp/10)%10);break;
case 3:printf("POUR(%d,%d)\n",(tmp/10)%10,tmp%10);
}
}
delete steps;
return ;
}
fill(1,cnt); fill(2,cnt);
drop(1,cnt); drop(2,cnt);
pour(1,cnt); pour(2,cnt);
cmp1++;
}
puts("impossible");
return ;
}
int main()
{
while(scanf("%d%d%d",&v1,&v2,&c)!=-1)
bfs();
return 0;
}