题目大意:
你有两个瓶子,容量分别为A,B,有以下三种操作:
1.FILL(i) 将i灌满。
2.DROP(i) 将i倒空。
3.POUR(i,j) 将i中的水倒入j中。可能j已满,i没倒空或j未满,i已空。
问最少操作几次可以使其中一个杯子容量为C,若无法成立,则输出"impossible"。
解题思路:
从A为空,B为空为起始状态开始宽搜,一共有6个方向。
代码:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
struct element{
int a,b,step,before,
operation;//0代表fill(a),1代表fill(b),2代表drop(a),3代表drop(b),4代表pour(a,b),5代表pour(b,a);
element(){};
element(int _a,int _b,int _step,int _before,int _operation){
a = _a;
b = _b;
step = _step;
before = _before;
operation = _operation;
}
};
element q[10005];
int head,root;
bool f[105][105];
int a,b,c;
int ans[10005];
string s[6];
int main()
{
cin >> a >> b >> c;
s[0] = "FILL(1)";
s[1] = "FILL(2)";
s[2] = "DROP(1)";
s[3] = "DROP(2)";
s[4] = "POUR(1,2)";
s[5] = "POUR(2,1)";
memset(f,true,sizeof(f));
//初始化队列
q[0].a = 0;
q[0].b = 0;
q[0].step = 0;
q[0].before = -1;
q[0].operation = -1;
head = 0;
root = 1;
f[0][0] = false;
//bfs
while(head < root){
element temp;
temp = q[head];
if(temp.a == c || temp.b == c) break;
//fill(1)
if(f[a][temp.b]){f[a][temp.b] = false; q[root] = element(a,temp.b,temp.step+1,head,0); root ++;}
//fill(2)
if(f[temp.a][b]){f[temp.a][b] = false; q[root] = element(temp.a,b,temp.step+1,head,1); root ++;}
//drop(1)
if(f[0][temp.b]){f[0][temp.b] = false; q[root] = element(0,temp.b,temp.step+1,head,2); root ++;}
//drop(2)
if(f[temp.a][0]){f[temp.a][0] = false; q[root] = element(temp.a,0,temp.step+1,head,3); root ++;}
int tempA,tempB;
//pour(1,2)
if(temp.a + temp.b > b){
tempB = b;
tempA = temp.a + temp.b - b;
}
else{
tempB = temp.a + temp.b;
tempA = 0;
}
if(f[tempA][tempB]){f[tempA][tempB] = false; q[root] = element(tempA,tempB,temp.step+1,head,4); root ++;}
//pour(2,1)
if(temp.a + temp.b > a){
tempA = a;
tempB = temp.a + temp.b - a;
}
else{
tempA = temp.a + temp.b;
tempB = 0;
}
if(f[tempA][tempB]){f[tempA][tempB] = false; q[root] = element(tempA,tempB,temp.step+1,head,5); root ++;}
head ++;
}
if(head == root){
cout << "impossible" << endl;
return 0;
}
int t = head;
while(t > 0){
ans[q[t].step] = q[t].operation;
t = q[t].before;
}
cout << q[head].step << endl;
for(int i = 1; i <= q[head].step; i ++){
cout << s[ans[i]] << endl;;
}
return 0;
}