1.题意:给你两个容量为A和B的杯子,让你进行如下操作:
- 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 jis 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)
求其中一个杯子达到C容量水时最小的操作步数。
2.分析:
求最小步数,每次可以进行六种操作,转化为BFS;
这里吧两个杯子此时刻的状态作为一个元素存入队列!比较抽象运用BFS到具体实际问题里,这个是很难想的也是这个题目的亮点
代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
int A,B,C;
struct Node
{
int id,v1,v2;//此状态下的步数和第一个容器的水量和第二个容器的水量
vector<int> op;//保存操作
//Node(int i,int a,int b):id(i),v1(a),v2(b) {op.clear();}
};
bool judge[105][105];
char oper[6][10] = {"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
bool BFS()
{
queue<Node> que;
Node q;
q.id = 0;
q.v1 = 0;
q.v2 = 0;
q.op.clear();
que.push(q);
while(!que.empty()){
Node node = que.front();
que.pop();
if(node.v1==C||node.v2==C){//输出
printf("%d\n",node.id);
for(int i = 0;i<node.op.size();i++){
printf("%s\n",oper[node.op[i]]);
}
return true;
}
for(int i = 0;i<6;i++){
Node another;
another.id = node.id + 1;
another.op = node.op;
another.op.push_back(i);
if(i==0){//进行六种操作
if(node.v1==A)continue;
another.v1 = A;
another.v2 = node.v2;
if(!judge[another.v1][another.v2]){
judge[another.v1][another.v2] = 1;
que.push(another);
}
}
else if(i==1){
if(node.v2==B)continue;
another.v1 = node.v1;
another.v2 = B;
if(!judge[another.v1][another.v2]){
judge[another.v1][another.v2] = 1;
que.push(another);
}
}
else if(i==2){
if(node.v1==0)continue;
another.v1 = 0;
another.v2 = node.v2;
if(!judge[another.v1][another.v2]){
judge[another.v1][another.v2] = 1;
que.push(another);
}
}
else if(i==3){
if(node.v2==0)continue;
another.v1 = node.v1;
another.v2 = 0;
if(!judge[another.v1][another.v2]){
judge[another.v1][another.v2] = 1;
que.push(another);
}
}
else if(i==4){
if(node.v1==0||node.v2==B)continue;
int v = B - node.v2;
if(node.v1>=v){
another.v1 = node.v1 - v;
another.v2 = B;
}
else if(node.v1<v){
another.v1 = 0;
another.v2 = node.v2 + node.v1;
}
if(!judge[another.v1][another.v2]){
judge[another.v1][another.v2] = 1;
que.push(another);
}
}
else if(i==5){
if(node.v1==A||node.v2==0)continue;
int v = A - node.v1;
if(node.v2>=v){
another.v1 = A;
another.v2 = node.v2 - v;
}
else if(node.v2<v){
another.v1 = node.v2 + node.v1;
another.v2 = 0;
}
if(!judge[another.v1][another.v2]){
judge[another.v1][another.v2] = 1;
que.push(another);
}
}
}
}
return false;
}
int main()
{
scanf("%d%d%d",&A,&B,&C);
memset(judge,0,sizeof(judge));
if(!BFS())printf("impossible\n");
return 0;
}