【编程题】
给你两个烧杯,其容积分别是A升和B升。允许进行下列操作:
1.FILL(i) 从水管接水将烧杯i灌满((1 ≤ i ≤ 2)
2.DROP(i) 将第i个烧杯倒空
3.POUR(i,j) 将烧杯i的水倒进烧杯j;并且倒完后要么烧杯j是满的(烧杯i中也许有剩水),要么烧杯i是空的(此时烧杯i的水应该全部倒进烧杯j)。
写一个程序寻找最少的操作序列,使得这两个烧杯中的某一个烧杯中只剩C升水。
输入
仅仅1行,是数字A,B,C。它们都是整数,范围1到100并且C≤max(A,B)。
输出
第1行是操作序列的长度K。接下来的K行中,每行描述一次操作。如果存在多个最小长度序列,可以输出它们中间的任何一个。如果目标不可达,输出impossible。
样例输入
3 5 4
样例输出
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)
(简单的宽度优先搜索,不过要先判断最多多少种情况)
#include<iostream>
#include<stdlib.h>
#include<stack>
using namespace std;
stack<int> s;
typedef struct{
int a;
int b;
int fa;
int op;
}ST;
char operation[6][20] =
{
"FILL(1)",
"FILL(2)",
"DROP(1)",
"DROP(2)",
"POUR(1,2)",
"POUR(2,1)"
};
int vis[100][100];
ST arr[10000];
int main()
{
ST now;
int A,B,C;
int prior,next,pos;
cin>>A>>B>>C;
arr[0].a = 0;
arr[0].b = 0;
arr[0].fa = -1;
prior = 0; next = 1;
while(prior < next)
{
now = arr[prior];
if(now.a == C || now.b == C)
break;
if(now.a != A)
{
arr[next].a = A;
arr[next].b = now.b;
arr[next].fa = prior;
arr[next].op = 0;
if(!vis[arr[next].a][arr[next].b])
{
vis[arr[next].a][arr[next].b] = 1;
next++;
}
}
if(now.b != B)
{
arr[next].b = B;
arr[next].a = now.a;
arr[next].fa = prior;
arr[next].op = 1;
if(!vis[arr[next].a][arr[next].b])
{
vis[arr[next].a][arr[next].b] = 1;
next++;
}
}
if(now.a != 0)
{
arr[next].a = 0;
arr[next].b = now.b;
arr[next].fa = prior;
arr[next].op = 2;
if(!vis[arr[next].a][arr[next].b])
{
vis[arr[next].a][arr[next].b] = 1;
next++;
}
}
if(now.b != 0)
{
arr[next].b = 0;
arr[next].a = now.a;
arr[next].fa = prior;
arr[next].op = 3;
if(!vis[arr[next].a][arr[next].b])
{
vis[arr[next].a][arr[next].b] = 1;
next++;
}
}
if(now.a != 0 && now.b != B)
{
if(now.a + now.b <= B)
{
arr[next].a = 0;
arr[next].b = now.a + now.b;
}
else
{
arr[next].a = now.a - (B-now.b);
arr[next].b = B;
}
arr[next].fa = prior;
arr[next].op = 4;
if(!vis[arr[next].a][arr[next].b])
{
vis[arr[next].a][arr[next].b] = 1;
next++;
}
}
if(now.b != 0 && now.a != A)
{
if(now.a + now.b <= A)
{
arr[next].b = 0;
arr[next].a = now.a + now.b;
}
else
{
arr[next].b = now.b - (A-now.a);
arr[next].a = A;
}
arr[next].fa = prior;
arr[next].op = 5;
if(!vis[arr[next].a][arr[next].b])
{
vis[arr[next].a][arr[next].b] = 1;
next++;
}
}
prior++;
}
if(prior >= next) cout<<"impossible"<<endl;
else
{
pos = prior;
while(arr[pos].fa != -1)
{
s.push(arr[pos].op);
pos = arr[pos].fa;
}
while(!s.empty())
{
cout<<operation[s.top()]<<endl;
s.pop();
}
}
//system("pause");
return 0;
}