这是一道代码量较每一种并不是都有六种操作,
第一次操作必定要将a杯或b杯倒满,
接下来操作数也有限定
①如果a满则不能倒掉b,(b同理)
②如果a、b的两种状态在之前已经出现过一次,则没必要再操作;
这两个已经可以排掉大部分操作;
#include<iostream>
#include<cstdio>
#include<queue>
#include<map>
#include<cstring>
using namespace std;
string Ans[6] = { "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)",};
int a, b, c;
struct nod{
int x, y, step;
queue<int>s;
};
bool vis[105][105];
nod op4(nod k){
nod t = k;
k.y += k.x;
if(k.y > b) k.y = b;
k.x = t.x + t.y - k.y;
k.s.push(4);
k.step++;
return k;
}
nod op5(nod k){
nod t = k;
k.x += k.y;
if(k.x > a) k.x = a;
k.y = t.x + t.y - k.x;
k.s.push(5);
k.step++;
return k;
}
int main(){
cin >> a >> b >> c;
memset(vis, false, sizeof(vis));
vis[0][0] = true;
vis[a][0] = true;
vis[0][b] = true;
queue<nod>q;
nod ans;
ans.x = a;
ans.y = 0;
ans.step = 1;
ans.s.push(0);
q.push(ans);
//倒满a
ans.x = 0;
ans.y = b;
ans.s.pop();
ans.s.push(1);
q.push(ans); // 初始化 倒满b
while(!q.empty()){
ans = q.front();
if(ans.x == c || ans.y == c) break;
nod temp = ans;
nod tempx = op4(temp), tempy = op5(temp);
q.pop();
if(!vis[a][temp.y]){
temp.s.push(0);
temp.x = a;
temp.step++;
q.push(temp);
vis[a][temp.y] = true;
temp = ans;
} //倒满a
if(!vis[temp.x][b]){
temp.s.push(1);
temp.step++;
temp.y = b;
vis[temp.x][b] = true;
q.push(temp);
temp = ans;
} //倒满b
if(!vis[0][temp.y]){
temp.s.push(2);
temp.step++;
temp.x = 0;
vis[0][temp.y] = true;
q.push(temp);
temp = ans;
} //倒掉a
if(!vis[temp.x][0]){
temp.s.push(3);
temp.step++;
temp.y = 0;
vis[temp.x][0] = true;
q.push(temp);
temp = ans;
}
if(!vis[tempx.x][tempx.y]){
q.push(tempx);
vis[tempx.x][tempx.y] = true;
}
if(!vis[tempy.x][tempy.y]){
q.push(tempy);
vis[tempy.x][tempy.y] = true;
}
}
if(ans.x != c && ans.y != c) cout << "impossible";
else {
cout << ans.step << endl;
while(!ans.s.empty()){
cout << Ans[ans.s.front()] << endl;
ans.s.pop();
}
}
return 0;
}