N - 非常可乐
================================================================================================================================
不用想的太复杂,其实就是一道广搜题,
三个瓶子有六种操作
s瓶→n瓶 s瓶→m瓶
n瓶→m瓶 n瓶→s瓶
m瓶→n瓶 m瓶→s瓶
只是比迷宫题的 上下左右 4个操作多了2种操作
然后判定条件变成 两个瓶子里的液体相同&&另一个瓶子里为空
再按照一般广搜的套路来,定义好列表,head ,tail 开始进行广搜
tail[head] 的初始状态 即三个瓶子的初始状态
s瓶 满的 n瓶 空的 m瓶 空的 step = 0
================================================================================================================================
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 int s,n,m; 6 struct Node{ 7 int s,n,m; 8 int step; 9 void in(int a,int b,int c,int d) 10 { 11 s=a,n=b,m=c;step=d; 12 } 13 }tail[10000]; 14 bool book[200][200]; 15 bool flag; 16 int head,top; 17 void caozuo(int i,int& ts,int& tn,int& tm) 18 { 19 if(i==1) // s瓶→n瓶 20 { 21 tn+=ts;ts=0; //s瓶全部倒入 n瓶 22 //tn表示当前的液体 , n表示最多可容纳多少 23 if(tn>n) ts = tn-n,tn=n; //如果n瓶溢出了,则溢出的返回给s瓶 24 } 25 //下面的操作原理跟上面一样 26 if(i==2) // s瓶→m瓶 27 { 28 tm+=ts;ts=0; 29 if(tm>m) ts = tm-m,tm=m; 30 } 31 if(i==3) // n瓶→s瓶 32 { 33 ts+=tn;tn=0; 34 if(ts>s) tn = ts-s,ts=s; 35 } 36 if(i==4) // n瓶→m瓶 37 { 38 tm+=tn;tn=0; 39 if(tm>m) tn = tm-m,tm=m; 40 } 41 if(i==5) // m瓶→s瓶 42 { 43 ts+=tm;tm=0; 44 if(ts>s) tm = ts-s,ts=s; 45 } 46 if(i==6) // m瓶→n瓶 47 { 48 tn+=tm;tm=0; 49 if(tn>n) tm = tn-n,tn=n; 50 } 51 } 52 int main() 53 { 54 while(~scanf("%d %d %d",&s,&n,&m)&&s+n+m) 55 { 56 flag=0;memset(book,0,sizeof(book)); //初始化 57 if(n == m) printf("1\n"); //如果n==m,只需一步就可以达到目的 58 else 59 { 60 head = 1;top = 2; 61 tail[1].in(s,0,0,0); //队列【1】初始化 62 book[0][0]=1; 63 while(head<top) 64 { 65 for(int i = 1;i<=6;++i) 66 { 67 int ts = tail[head].s; 68 int tn = tail[head].n; 69 int tm = tail[head].m; 70 caozuo(i,ts,tn,tm); //执行六个步骤 71 if(book[tn][tm]==1) continue; 72 if(book[tn][tm]==0) 73 { 74 book[tn][tm]=1; 75 tail[top].in(ts,tn,tm,tail[head].step+1); 76 ++top; 77 } 78 //printf("ts : %d tn: %d tm: %d %d\n",ts,tn,tm,tail[top-1].step); 79 //↑可以直观的看到每一步三个瓶子的状况 80 if(tn==tm&&ts==0||tn==ts&&tm==0||ts==tm&&tn==0) {flag=1;break;} 81 } 82 head++; 83 if((flag==1)) break; 84 } 85 if(flag) printf("%d\n",tail[top-1].step); 86 else printf("NO\n"); 87 88 } 89 } 90 }