非常经典的搜索题。
为什么可以用搜索呢?
因为三个杯子,他们互相倒的可能性是一定的,而互相倒的可能性也是一定的。
即六种互相倒的可能性,还有满或不满两种可能。
int S, N, M;
int vis[101][101][101];//标记数组
int cup[3];//三个杯子的最大容量
struct node
{
int x[3];//三个杯子的水量情况
int step;//当前步数
};
struct node head;
queue <struct node> q;
int main(){
while (cin >> S >> N >> M) {
if(S == 0)
break;
if (S % 2 == 1){
cout << "NO" << endl;
continue;
}
//剪枝
Init();
bfs();
}
return 0;
}
void Init(){
memset(vis, 0, sizeof(vis));
cup[0] = S; cup[1] = N; cup[2] = M;
while(!q.empty())//队列的情况,为下一次数据的读入做准备
q.pop();
struct node tmp;
tmp.x[0] = S; tmp.x[1] = 0; tmp.x[2] = 0; tmp.step = 0;
q.push(tmp);
vis[S][0][0] = 1;
}
//初始化函数
void bfs(){
while (!q.empty()) {
head = q.front();
q.pop();//出队挨批
for (int i=0; i<3; i++){// 三个杯子
if (head.x[i] > 0){
for (int j=0; j<3; j++) {//这里一直在想怎么直接排出自己给自己的情况,但是好像做不到
if (i == j) continue;//自己不能倒给自己。
struct node tmp;
get_info(tmp);//处理头信息
if (head.x[i] <= cup[j] - head.x[j]){//没满出来
tmp.x[j] = tmp.x[i] + tmp.x[j];
tmp.x[i] = 0;
tmp.step ++;
}else{
tmp.x[i] = tmp.x[i] - (cup[j] - tmp.x[j]);
tmp.x[j] = cup[j];
tmp.step ++;
}
if (judge(tmp)){//是否已经半
cout << tmp.step << endl;
return;
}else{
if (vis[tmp.x[0]][tmp.x[1]][tmp.x[2]] == 0){
q.push(tmp);
vis[tmp.x[0]][tmp.x[1]][tmp.x[2]] = 1;//标记
}
}
}
}
}
}
cout << "NO" << endl;
}
bool judge(struct node tmp)//判断结果是否出来了
{
if((tmp.x[0]==S/2&&tmp.x[1]==S/2)||(tmp.x[0]==S/2&&tmp.x[2]==S/2)||(tmp.x[1]==S/2&&tmp.x[2]==S/2))
return true;
else
return false;
}
还是太菜了。 唉。= =。