【题目链接】
http://poj.org/problem?id=3414
题目意思
给两个容积的,一共三种操作倒掉一个杯子,问你经过多少次操作能得到需要的水。如果不能输出“impossible”。
解题思路
和非常可乐非常像,每次3种操作都遍历,记录路径。
代码部分
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <map>
using namespace std;
#define LL long long
#define inf 0x3f3f3f3
const int N = 1e5+5;
int v[5];
int vis[105][105];
int num = 0;
struct cup
{
int v[5],i,j,s; ///i表示那个水杯,j表示操作
cup *pre; ///记录路径
}temp,t[305];
void show(cup x) ///输出函数
{
if (x.pre == NULL)
return;
else show(*x.pre);
if (x.j == 0)
printf("DROP(%d)\n",x.i);
else if (x.j == 1)
printf("FILL(%d)\n",x.i);
else printf("POUR(%d,%d)\n",x.i,3-x.i);
}
void pour (int x) ///倒水
{
int y = 1-x;
int sum = temp.v[x]+temp.v[y];
if (sum > v[y]) ///超出容量时候
temp.v[y] = v[y];
else temp.v[y] = sum;
temp.v[x] = sum-temp.v[y];
}
void bfs ()
{
queue<cup> q;
temp.v[0] = temp.v[1] = temp.s = 0;
temp.i = temp.j = -1;
temp.pre = NULL;
q.push(temp);
vis[0][0] = 1;
while (!q.empty())
{
t[++num] = q.front();
q.pop();
if (t[num].v[0] == v[2] || t[num].v[1] == v[2])
{
printf("%d\n",t[num].s);
show(t[num]);
return;
}
for (int i = 0; i < 2; i++) ///选择要倒出的杯子
{
for (int j = 0; j < 3; j++) ///选择被到入的杯子
{
temp = t[num];
temp.pre = &t[num];
temp.i = i+1;
temp.j = j;
if (j == 0) ///倒掉水
temp.v[i] = 0;
else if (j == 1) ///填满
temp.v[i] = v[i];
else
pour(i); ///i到向1-i
if (!vis[temp.v[0]][temp.v[1]])
{
temp.s++;
q.push(temp);
vis[temp.v[0]][temp.v[1]] = 1;
}
}
}
}
printf("impossible\n");
}
int main ()
{
while (~scanf("%d %d %d",&v[0],&v[1],&v[2]))
{
num = 0;
memset(vis,0,sizeof(vis));
bfs();
}
}