【POJ 3414 --- Pots】BFS
Description
You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:
FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap;
DROP(i) empty the pot i to the drain;
POUR(i,j) pour from pot i to pot j; after this operation either the pot j is full (and there may be some water
left in the pot i), or the pot i is empty (and all its contents have been moved to the pot j).
Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots.
Input
On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C≤max(A,B).
Output
The first line of the output must contain the length of the sequence of operations K. The following K lines must each describe one operation. If there are several sequences of minimal length, output any one of them. If the desired result can’t be achieved, the first and only line of the file must contain the word ‘impossible’.
Sample Input
3 5 4
Sample Output
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)
解题思路
根据题意知:一共只有6种操作,那么我们可以用bfs通过这6种方式来广搜。并且记录每次的操作就行。
利用bfs求最优解。将每次的操作和当前两个壶里的水记录到结构体中。
详情看代码:
AC代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define endl '\n'
const int MAXN = 105;
int a,b,c;
string s[6]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
bool vis[MAXN][MAXN];
struct Node
{
int a,b;
vector<int> v;
};
void bfs()
{
Node node;
node.a=0; node.b=0;
queue<Node> q;
q.push(node);
vis[0][0]=true;
while(!q.empty())
{
node=q.front();
q.pop();
if(node.a==c || node.b==c)
{
int len=node.v.size();
cout << len << endl;
for(int i=0;i<len;i++)
cout << s[node.v[i]] << endl;
return;
}
//s[0]
if(a-node.a>0)
{
Node n=node;
n.a=a;
n.v.push_back(0);
if(!vis[n.a][n.b]) q.push(n),vis[n.a][n.b]=true;
}
//s[1]
if(b-node.b>0)
{
Node n=node;
n.b=b;
n.v.push_back(1);
if(!vis[n.a][n.b]) q.push(n),vis[n.a][n.b]=true;
}
//s[2]
if(node.a>0)
{
Node n=node;
n.a=0;
n.v.push_back(2);
if(!vis[n.a][n.b]) q.push(n),vis[n.a][n.b]=true;
}
//s[3]
if(node.b>0)
{
Node n=node;
n.b=0;
n.v.push_back(3);
if(!vis[n.a][n.b]) q.push(n),vis[n.a][n.b]=true;
}
//s[4]
if(node.a && b-node.b>0)
{
Node n=node;
int x=node.a+node.b;
n.a=x>b ? x-b : 0;
n.b=x>b ? b : x;
n.v.push_back(4);
if(!vis[n.a][n.b]) q.push(n),vis[n.a][n.b]=true;
}
//s[5]
if(node.b && a-node.a>0)
{
Node n=node;
int x=node.a+node.b;
n.a=x>a ? a : x;
n.b=x>a ? x-a : 0;
n.v.push_back(5);
if(!vis[n.a][n.b]) q.push(n),vis[n.a][n.b]=true;
}
}
cout << "impossible" << endl;
}
int main()
{
SIS;
cin >> a >> b >> c;
bfs();
return 0;
}