题意:容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。能平分的话请输出最少要倒的次数,否则输出"NO"。
解法:广搜,每一个队头元素都要进行6次操作,如图进行了n->m一次操作:
对应的6中操作(S->N,S->M,N->S,N->M,M->S,M->N)
此图必须注意:n,m的意思为:瓶子n中此刻存在的可乐量为n,瓶子m中此刻存在的可乐量为m
注意:从一个瓶倒进另一个瓶时必须分两种情况,1:能装满2:不能装满
ac代码及测试数据:
View Code
#include<iostream> #include<queue> using namespace std; const int m=101; int map[m][m][m]; //map[]用作标记 struct node { int s,n,m; int step; }; int main() { queue<struct node>q; struct node temp; int s,n,m; int a,b,c; while(cin>>s>>n>>m,(s&&n&&m)) { if(s%2==1||(s/2>n&&s/2>m)) //s若为奇数或s的一半都大于n,m.不可能满足条件,直接退出 { cout<<"NO"<<endl; continue; } if(m>n) //确保s>n>m { c=n; n=m; m=c; } memset(map,0,sizeof(map)); a=temp.s=s; b=temp.n=0; c=temp.m=0; temp.step=0; map[a][b][c]=1; q.push(temp); while(!q.empty()) { if(q.front().m==s/2&&q.front().n==s/2&&q.front().s==0) { cout<<q.front().step<<endl; break; } if(q.front().m==0&&q.front().n==s/2&&q.front().s==s/2) { cout<<q.front().step<<endl; break; } if(q.front().m==s/2&&q.front().n==0&&q.front().s==s/2) { cout<<q.front().step<<endl; break; } //前三个if()判断是否满足条件 if(q.front().s>=n-q.front().n) { a=q.front().s-(n-q.front().n); b=n; temp.s=a; temp.n=b; temp.m=q.front().m; if(!map[a][b][q.front().m]) { map[a][b][q.front().m]=1; temp.step=q.front().step+1; q.push(temp); } } else { a=0; b=q.front().n+q.front().s; temp.s=a; temp.n=b; temp.m=q.front().m; if(!map[a][b][q.front().m]) { map[a][b][q.front().m]=1; temp.step=q.front().step+1; q.push(temp); } } if(q.front().s>=m-q.front().m) { a=q.front().s-(m-q.front().m); c=m; temp.s=a; temp.m=c; temp.n=q.front().n; if(!map[a][q.front().n][c]) { map[a][q.front().n][c]=1; temp.step=q.front().step+1; q.push(temp); } } else { a=0; b=q.front().n+q.front().s; temp.s=a; temp.n=b; temp.m=q.front().m; if(!map[a][b][q.front().m]) { map[a][b][q.front().m]=1; temp.step=q.front().step+1; q.push(temp); } } if(s-q.front().s>q.front().n) { a=q.front().n+q.front().s; b=0; temp.s=a; temp.n=b; temp.m=q.front().m; if(!map[a][b][q.front().m]) { map[a][b][q.front().m]=1; temp.step=q.front().step+1; q.push(temp); } } if(q.front().n>=m-q.front().m) { b=q.front().n-(m-q.front().m); c=m; temp.n=b; temp.m=c; temp.s=q.front().s; if(!map[q.front().s][b][c]) { map[q.front().s][b][c]=1; temp.step=q.front().step+1; q.push(temp); } } else { b=0; c=q.front().m+q.front().n; temp.n=b; temp.m=c; temp.s=q.front().s; if(!map[q.front().s][b][c]) { map[q.front().s][b][c]=1; temp.step=q.front().step+1; q.push(temp); } } if(s-q.front().s>q.front().m) { a=q.front().m+q.front().s; c=0; temp.s=a; temp.m=c; temp.n=q.front().n; if(!map[a][q.front().n][c]) { map[a][q.front().n][c]=1; temp.step=q.front().step+1; q.push(temp); } } if(q.front().m>=n-q.front().n) { c=q.front().m-(n-q.front().n); b=n; temp.m=c; temp.n=b; temp.s=q.front().s; if(!map[q.front().s][b][c]) { map[q.front().s][b][c]=1; temp.step=q.front().step+1; q.push(temp); } } else { c=0; b=q.front().n+q.front().m; temp.m=c; temp.n=b; temp.s=q.front().s; if(!map[q.front().s][b][c]) { map[q.front().s][b][c]=1; temp.step=q.front().step+1; q.push(temp); } } q.pop(); } if(q.empty()) cout<<"NO"<<endl; while(!q.empty()) q.pop(); } return 0; } 峰注:不明白请留言