题意:有两个杯子容量是A和B,水是无限的。得到C的水。
直接bfs
以两个杯中的水为状态,记得判重。
特判的数据要好好看看是否对,我就错了一发,搞了半天还不知道错在哪?
#include
#include
#include
#include
using namespace std;
char str[7][10] = {" ", "FILL(2)", "FILL(1)", "POUR(2,1)", "POUR(1,2)", "DROP(2)", "DROP(1)"};
struct node
{
int a, b;//状态
node() {}
node(int aa, int bb)
{
a = aa;
b = bb;
}
};
struct
{
int dir;//方式
int next;//上一个状态
}vis[100000];//判重
queue
que;
int ans;
void prin(int n)//输出路径
{
if(n == 0)
printf("%d\n", ans) ;
else
{
ans++;
prin(vis[n].next);
printf("%s\n", str[ vis[n].dir ] );
}
}
int a, b, c;
int f(int x, int y, node tmp, int n)
{
if(!vis[x*200+y].dir)
{
// printf("\t%d==%d--%d\n", n, x, y);
vis[x*200+y].next = tmp.a*200+tmp.b;//记录上次的位置,便于输出路径
vis[x*200+y].dir = n; //记录方式
if(x == c || y == c) return x*200+y;//如果满足条件返回
que.push(node(x, y));
}
return 0;
}
int bfs()
{
while(!que.empty()) que.pop();
que.push(node(0, 0));
memset(vis, 0, sizeof(vis));
vis[0].dir = -1;
vis[0].next = -1;
while(!que.empty())
{
node tmp = que.front();
que.pop();
int x = tmp.a, y = b;//把B倒满
int temp = f(x, y, tmp, 1); if(temp) return temp;
x = a, y = tmp.b;//把A倒满
temp = f(x, y, tmp, 2); if(temp) return temp;
x = tmp.a+tmp.b;//B中的水倒入A中
if(x > a) x = a, y = tmp.a+tmp.b-a;
else y = 0;
temp = f(x, y, tmp, 3); if(temp) return temp;
y = tmp.a+tmp.b;//A中的水倒入B中
if(y > b) y = b, x = tmp.a+tmp.b-b;
else x = 0;
temp = f(x, y, tmp, 4); if(temp) return temp;
x = tmp.a, y = 0;//把B中的水倒掉
temp = f(x, y, tmp, 5); if(temp) return temp;
x = 0, y = tmp.b;//把A中的水倒掉
temp = f(x, y, tmp, 6); if(temp) return temp;
}
return -100;
}
int main(void)
{
while(~scanf("%d%d%d", &a, &b, &c))
{
ans = 0;
if(0 == c)//
{
printf("0\n");
continue;
}
int tmp = bfs();
if(tmp == -100) printf("impossible\n");
else
{
prin(tmp);
}
}
return 0;
}