给出三个数A,B,C,A,B代表两个容器,问是否能通过以下几种操作,把A或B里的水变成C。
FILL(i) 把i容器中倒满水,DROP(i) 把i容器中的水倒掉,POUR(i,j) 把i容器中的水倒到j中。
如果能做到,输出需要的最小步数,并输出每一步的操作,如果不能输出impossible。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int a,b,c;
int book[110][110];
typedef struct
{
int i,j;
vector<int> s;
}state;
void bfs()
{
memset(book,0,sizeof(book));
vector<int> t;
queue<state> q;
state n,p;
n.i = 0;
n.j = 0;
n.s = t;
q.push(n);
while(!q.empty())
{
n = q.front();
if(n.i==c || n.j == c)
{
int i;
printf("%d\n",n.s.size());
for(i=0;i<n.s.size();i++)
{
if(n.s[i]==1)
printf("FILL(1)");
if(n.s[i]==2)
printf("FILL(2)");
if(n.s[i]==3)
printf("DROP(1)");
if(n.s[i]==4)
printf("DROP(2)");
if(n.s[i]==5)
printf("POUR(1,2)");
if(n.s[i]==6)
printf("POUR(2,1)");
printf("\n");
}
return;
}
q.pop();
if(n.i != a)
{
p = n;
p.i = a;
if(book[p.i][p.j]==0)
{
book[p.i][p.j]=1;
p.s.push_back(1);
q.push(p);
}
}
if(n.j != b)
{
p = n;
p.j = b;
if(book[p.i][p.j]==0)
{
book[p.i][p.j]=1;
p.s.push_back(2);
q.push(p);
}
}
if(n.i != 0)
{
p = n;
p.i = 0;
if(book[p.i][p.j]==0)
{
book[p.i][p.j]=1;
p.s.push_back(3);
q.push(p);
}
}
if(n.j != 0)
{
p = n;
p.j = 0;
if(book[p.i][p.j]==0)
{
book[p.i][p.j]=1;
p.s.push_back(4);
q.push(p);
}
}
if(n.j != b)
{
p = n;
if(n.i >= (b - n.j))
{
p.j = b;
p.i = n.i - (b - n.j);
}
else
{
p.i = 0;
p.j = n.j + n.i;
}
if(book[p.i][p.j]==0)
{
book[p.i][p.j]=1;
p.s.push_back(5);
q.push(p);
}
}
if(n.i != a)
{
p = n;
if(n.j >= (a - n.i))
{
p.i = a;
p.j = n.j - (a - n.i);
}
else
{
p.j = 0;
p.i = n.j + n.i;
}
if(book[p.i][p.j]==0)
{
book[p.i][p.j]=1;
p.s.push_back(6);
q.push(p);
}
}
}
printf("impossible\n");
}
int main(void)
{
while(scanf("%d%d%d",&a,&b,&c)==3)
{
bfs();
}
return 0;
}
输出:
6 FILL(2) POUR(2,1) DROP(1) POUR(2,1) FILL(2) POUR(2,1)