有4个红酒瓶子,它们的容量分别是:9升, 7升, 4升, 2升
开始的状态是 [9,0,0,0],也就是说:第一个瓶子满着,其它的都空着。
允许把酒从一个瓶子倒入另一个瓶子,但只能把一个瓶子倒满或把一个瓶子倒空,不能有中间状态。这样的一次倒酒动作称为1次操作。
假设瓶子的容量和初始状态不变,对于给定的目标状态,至少需要多少次操作才能实现?
本题就是要求你编程实现最小操作次数的计算。
输入:最终状态(逗号分隔)
输出:最小操作次数(如无法实现,则输出-1)
例如:
输入:
9,0,0,0
应该输出:
0
输入:
6,0,0,3
应该输出:
-1
输入:
7,2,0,0
应该输出:
2
当初比赛的时候做的这道题,那时候还没有学习搜索。当时竟然想要用枚举。
可想而知,全是泪水啊。
回来,就学习了大牛的搜索思路。总算是做出来了。
思路:其实就是模拟倒酒的过程,有a,b,c,d四个酒杯,然后有a->b,a->c,a->d,b>a,b->c,b->d........这12种倒酒方式。
在搜索的过程中,要注意有几种情况不能倒酒:
1、a杯中的酒不能倒在a杯中。
2.a杯为空,不能倒酒
3、a->b,如果b杯已满,不能倒酒。
最后再利用一个四位数组,来记录已经经历过的状态。

1 #include<iostream> 2 #include<queue> 3 using namespace std; 4 5 typedef struct 6 { 7 int now[4]; 8 int step; 9 }state; 10 int full[4] = {9 , 7 , 4 , 2}; 11 int vis[10][8][5][3]; //用来判断是否是已经记录的状态 12 13 int bfs(state& temp , int i , int j) 14 { 15 if(i == j) return 0; //i中的水不能倒在i中 16 if(temp.now[i] == 0) return 0; //i中没有水,不能操作 17 if(temp.now[j] == full[j]) return 0; //j中水已满,不能操作 18 if(temp.now[i] + temp.now[j] <= full[j]) //进入倒水环节 19 { 20 temp.now[j] = temp.now[j] + temp.now[i]; //将i中的水全部倒入j中 21 temp.now[i] = 0; 22 } 23 else //将j倒满 24 { 25 temp.now[i] = temp.now[i] - (full[j] - temp.now[j]); 26 temp.now[j] = full[j]; 27 } 28 if(vis[temp.now[0]][temp.now[1]][temp.now[2]][temp.now[3]]) 29 {return 0;} 30 else vis[temp.now[0]][temp.now[1]][temp.now[2]][temp.now[3]] = 1; 31 temp.step++; 32 return 1; 33 } 34 int main() 35 { 36 int end[4]; //需要输入的最后状态 37 int i , j , flag; 38 while(cin>>end[0]>>end[1]>>end[2]>>end[3]) 39 { 40 queue<state>q; 41 flag = 0; 42 memset(vis , 0 , sizeof(vis)); 43 if(end[0]+end[1]+end[2]+end[3]!=9) //非法状态 44 {cout<<"-1"<<endl;flag = 1;} 45 if(end[0]>full[0]||end[1]>full[1]||end[2]>full[2]||end[3]>full[3]) 46 {cout<<"-1"<<endl;flag = 1;} //非法状态 47 state star; //初始状态 初始化 48 star.now[0] = 9; 49 star.now[1] = 0; 50 star.now[2] = 0; 51 star.now[3] = 0; 52 star.step = 0; 53 q.push(star); //将初始状态压入队列 54 while(!q.empty()) 55 { 56 state temp = q.front(); 57 q.pop(); 58 if(temp.now[0]==end[0]&&temp.now[1]==end[1]&&temp.now[2]==end[2]&&temp.now[3]==end[3]) 59 { 60 flag = 1; 61 printf("%d\n" , temp.step); 62 break; 63 } 64 for(i = 0; i < 4; i++) 65 { 66 for(j = 0; j < 4; j++) 67 { 68 state temp2 = temp; 69 if(bfs(temp2 , i , j)) 70 q.push(temp2); 71 } 72 } 73 } 74 if(!flag) cout<<"-1"<<endl; 75 } 76 return 0; 77 }