题目描述
代码
#include <iostream>
#include <queue>
#include <cstring>
#define N 105
using namespace std;
struct Status{
int ml[3];
int t;
Status(int _ml[], int _t = 0){
ml[0] = _ml[0];
ml[1] = _ml[1];
ml[2] = _ml[2];
t = _t;
}
Status(int a, int b, int c, int _t = 0){
ml[0] = a;
ml[1] = b;
ml[2] = c;
t = _t;
}
};
int visited[N][N][N];
int main(){
freopen("in.txt", "r", stdin);
int vol[3];
while(cin >> vol[0] >> vol[1] >> vol[2]){
if(vol[0] == 0 && vol[1] == 0 && vol[2] == 0){
break;
}
if(vol[0] % 2 != 0){ // 一半为小数,不符合
cout << "NO" << endl;
continue;
}
int half_ml = vol[0] / 2;
// 初始化visited
memset(visited, 0, sizeof(visited));
queue<Status> que;
que.push(Status(vol[0], 0, 0, 0));
visited[vol[0]][0][0] = 1;
bool finished = false; // 完成平分?
while(!que.empty()){
Status status = que.front();
que.pop();
// 判断是否平分
for(int i = 0; i < 3 && !finished; i++){
for(int j = 0; j < 3 && !finished; j++){
if(i != j && status.ml[i] == half_ml && status.ml[j] == half_ml){
finished = true;
}
}
}
if(finished){ // 平分完成,退出循环
cout << status.t << endl;
break;
}
// 对每个杯子
for(int i = 0; i < 3; i++){
if(status.ml[i] == 0){ // 为0ml
continue;
}
// 此杯子给另外两个杯子倒可乐
for(int j = 0; j < 3; j++){
if(i == j || status.ml[j] == vol[j]){ // 不是另一杯子或者另一杯子满
continue;
}
// _ml为倒入后的状态,先初始化
int _ml[3];
for(int l = 0; l < 3; l++){
_ml[l] = status.ml[l];
}
// 倒给另外一个杯子可乐,把此杯子倒完或者装满另一杯子
if(vol[j] - status.ml[j] > status.ml[i]){
_ml[i] = 0;
_ml[j] = status.ml[j] + status.ml[i];
}else{
_ml[i] = status.ml[i] - (vol[j] - status.ml[j]);
_ml[j] = vol[j];
}
// 状态入队
if(!visited[_ml[0]][_ml[1]][_ml[2]]){
que.push(Status(_ml, status.t + 1));
visited[_ml[0]][_ml[1]][_ml[2]] = 1;
}
}
}
}
if(!finished){
cout << "NO" << endl;
}
}
return 0;
}