题目链接:点击这里
难点还是在于状态的定义及去重。
struct node {
int a, b; //a,b分别为A,B瓶的水量
int op;
int pre;
}q[10010];
这样就可以通过 进行标记去重。
AC代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
using namespace std;
//加满A 加满B 倒光A 倒光B A->B B->A
char str[15][15] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
int A, B, C;
bool vis[110][110]; //标记去重
int step[10010]; //Print里用来记录最后路径
struct node {
int a, b; //分别为A、B瓶的水量
int op;
int pre;
}q[10010];
void Print(int idx)
{
int cnt = 0;
while(idx!=0)
{
step[cnt++] = q[idx].op;
idx = q[idx].pre;
}
printf("%d\n", cnt);
for(int i = cnt-1; i >= 0; i--)
printf("%s\n", str[step[i]]);
}
int front = 0;
int rear = 1;
void BFS()
{
q[front].a = 0;
q[front].b = 0;
vis[0][0] = true;
while(front<rear)
{
if(q[front].a==C || q[front].b==C)
{
Print(front);
return;
}
for(int i = 0; i < 6; i++)
{
int newa, newb;
if(i == 0) //加满A
{
newa = A;
newb = q[front].b;
}
else if(i == 1) //加满B
{
newa = q[front].a;
newb = B;
}
else if(i == 2) //倒光A
{
newa = 0;
newb = q[front].b;
}
else if(i == 3) //倒光B
{
newa = q[front].a;
newb = 0;
}
else if(i == 4) //A->B
{
if(q[front].a + q[front].b < B) //不能把B灌满,就使A空
{
newa = 0;
newb = q[front].a + q[front].b;
}
else //能把B灌满
{
newa = q[front].a-(B-q[front].b);
newb = B;
}
}
else if(i == 5) //B->A
{
if(q[front].a + q[front].b < A) //不能把A灌满,就使B空
{
newa = q[front].a + q[front].b;
newb = 0;
}
else //能把A灌满
{
newa = A;
newb = q[front].b-(A-q[front].a);
}
}
if(!vis[newa][newb])
{
q[rear].a = newa;
q[rear].b = newb;
q[rear].op = i;
q[rear].pre = front;
vis[newa][newb] = true;
rear++;
}
}
front++;
}
printf("impossible\n");
return;
}
int main()
{
while(~scanf("%d%d%d", &A, &B, &C))
{
memset(vis, 0, sizeof(vis));
BFS();
}
return 0;
}