给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作
FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);
DROP(i) 将第i个容器抽干
POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)
现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程
Input
有且只有一行,包含3个数A,B,C(1<=A,B<=100,C<=max(A,B))
Output
第一行包含一个数表示最小操作数K
随后K行每行给出一次具体操作,如果有多种答案符合最小操作数,输出他们中的任意一种操作过程,如果你不能使两个容器中的任意一个满足恰好C升的话,输出“impossible”
Sample Input
3 5 4
Sample Output
6 FILL(2) POUR(2,1) DROP(1) POUR(2,1) FILL(2) POUR(2,1)
思路:很明显要用BFS来做,题不难,主要是需要比较麻烦,需要不断将满足条件的压入队列,然后再不断取出来判断,另外需要用数组标记,用一个结构体数组来存放父节点,方便最后输出。
#include<set>
#include<map>
#include<stack>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e2 + 10;
int A, B, C;
struct node
{
int x, y;
int step;
int f;
};
node fa[maxn * 3][maxn * 3][maxn * 3];
bool vis[maxn * 10][maxn * 10];
bool flag = false;
void bfs()
{
queue<node> q;
q.push(node{0, 0, 0});
int cnt = 0;
while(!q.empty())
{
node tmp = q.front();
q.pop();
if(tmp.x == C || tmp.y == C)
{
flag = true;
stack<int> que;
cout << tmp.step << endl;
node pre = tmp;
while(1)
{
if(pre.x == 0 && pre.y == 0 || pre.step == 0)
break;
que.push(pre.f);
pre = fa[pre.x][pre.y][pre.step];
}
while(!que.empty())
{
int tt = que.top();
que.pop();
if(tt == 1)
cout << "FILL(1)" << endl;
else if(tt == 2)
cout << "FILL(2)" << endl;
else if(tt == 3)
cout << "DROP(1)" << endl;
else if(tt == 4)
cout << "DROP(2)" << endl;
else if(tt == 5 || tt == 6)
cout << "POUR(1,2)" << endl;
else if(tt == 7 || tt == 8)
cout << "POUR(2,1)" << endl;
}
return;
}
if(tmp.x < A && !vis[A][tmp.y])
{
vis[A][tmp.y] = true;
q.push(node{A, tmp.y, tmp.step + 1, 1});
fa[A][tmp.y][tmp.step + 1] = tmp;
}
if(tmp.y < B && !vis[tmp.x][B])
{
vis[tmp.x][B] = true;
q.push(node{tmp.x, B, tmp.step + 1, 2});
fa[tmp.x][B][tmp.step + 1] = tmp;
}
if(tmp.x > 0 && !vis[0][tmp.y])
{
vis[0][tmp.y] = true;
q.push(node{0, tmp.y, tmp.step + 1, 3});
fa[0][tmp.y][tmp.step + 1] = tmp;
}
if(tmp.y > 0 && !vis[tmp.x][0])
{
vis[tmp.x][0] = true;
q.push(node{tmp.x, 0, tmp.step + 1, 4});
fa[tmp.x][0][tmp.step + 1] = tmp;
}
if(tmp.x > 0 && tmp.y < B)
{
int num = tmp.y + tmp.x;
if(num > B && !vis[num - B][B])
{
vis[num - B][B] = true;
q.push(node{num - B, B, tmp.step + 1, 5});
fa[num - B][B][tmp.step + 1] = tmp;
}
else if(!vis[0][num])
{
vis[0][num] = true;
q.push(node{0, num, tmp.step + 1, 6});
fa[0][num][tmp.step + 1] = tmp;
}
}
if(tmp.x < A && tmp.y > 0)
{
int num = tmp.y + tmp.x;
if(num > A && !vis[A][num - A])
{
vis[A][num - A] = true;
q.push(node{A, num - A, tmp.step + 1, 7});
fa[A][num - A][tmp.step + 1] = tmp;
}
else if(!vis[num][0])
{
vis[num][0] = true;
q.push(node{num, 0, tmp.step + 1, 8});
fa[num][0][tmp.step + 1] = tmp;
}
}
}
}
int main()
{
cin >> A >> B >> C;
bfs();
if(!flag)
cout << "impossible" << endl;
return 0;
}