模拟倒水的过程,每次可以把第i个杯子的水向第j个杯子里面倒,这可能出现新的状态,不停的更新状态,指导某两个杯子的水等于S/2说明找到答案,如果所有状态搜索完毕仍然不能均分,则退出。
注意:如果S是奇数,一定不能均分,因为所有杯子的体积都是整数,不可能倒出有小数的水。
AC代码
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100 + 5;
int d[maxn][maxn], s, n, m;
struct node{
int s, n, m;
node(){
}
node(int s, int n, int m):s(s), n(n), m(m){
}
};
int bfs(){
int cup[]={s, n, m};
memset(d, -1, sizeof(d));
queue<node>q;
q.push(node(s, 0, 0)); //初始状态
d[0][0] = 0;
while(!q.empty()){
node p = q.front();
q.pop();
int x = p.s, y = p.n, z = p.m;
if(x == s / 2 && y == s /2 || (x == s / 2 && z == s /2) || (y == s / 2 && z == s /2)) return d[y][z];
int a[3];
for(int i = 0; i < 3; ++i)
for(int j = 0; j < 3; ++j){
a[0] = x, a[1] = y, a[2] = z;
int pour = min(a[i], cup[j] - a[j]);
a[i] -= pour;
a[j] += pour;
if(d[a[1]][a[2]] == -1) {
d[a[1]][a[2]] = d[y][z] + 1;
q.push(node(a[0], a[1], a[2]));
}
}
}
return -1;
}
int main(){
while(scanf("%d%d%d", &s, &n, &m) == 3 && s){
int tp = -1;
if(!(s & 1)) tp = bfs();
if(tp == -1) printf("NO\n");
else printf("%d\n", tp);
}
return 0;
}
如有不当之处欢迎指出!