HDU ACM 1495 非常可乐->BFS倒水问题

来源:互联网 发布:红蜘蛛软件破解 编辑:程序博客网 时间:2024/06/05 17:05

题意:a,b,c三个数,分别代表可乐,两个杯子,三个容器可以互相倒,能不能把a平分,能的话输出最小步数,不能输出NO。

分析:求最小用BFS,对6种倒法进行BFS。另外如果a是奇数的话可以剪枝,因为不能平分。

#include<iostream>#include<queue>using namespace std;struct Node{int a,b,c;int s;      //步数};bool vis[102][102][102];  //标记状态bool bfs(int a,int b,int c,int& n){Node t,s;queue<Node> q;memset(vis,false,sizeof(vis));t.a=a;t.b=0;t.c=0;            //初始状态t.s=0;q.push(t);while(!q.empty()){t=q.front();q.pop();vis[t.a][t.b][t.c]=true;if(t.a*2==a&&t.b*2==a || t.a*2==a&&t.c*2==a || t.b*2==a&&t.c*2==a){n=t.s;return true;}if(t.a!=0)        //处理第一个瓶{if(t.a>b-t.b)s.a=t.a-(b-t.b),s.b=b,s.c=t.c,s.s=t.s+1;elses.a=0,s.b=t.a+t.b,s.c=t.c,s.s=t.s+1;if(!vis[s.a][s.b][s.c])vis[s.a][s.b][s.c]=true,q.push(s);if(t.a>c-t.c)s.a=t.a-(c-t.c),s.c=c,s.b=t.b,s.s=t.s+1;elses.a=0,s.b=t.b,s.c=t.a+t.c,s.s=t.s+1;if(!vis[s.a][s.b][s.c])vis[s.a][s.b][s.c]=true,q.push(s);}if(t.b!=0)        //处理第二个瓶{if(t.b>a-t.a)s.b=t.b-(a-t.a),s.a=a,s.c=t.c,s.s=t.s+1;elses.a=t.a+t.b,s.b=0,s.c=t.c,s.s=t.s+1;if(!vis[s.a][s.b][s.c])vis[s.a][s.b][s.c]=true,q.push(s);if(t.b>c-t.c)s.a=t.a,s.b=t.b-(c-t.c),s.c=c,s.s=t.s+1;elses.a=t.a,s.b=0,s.c=t.b+t.c,s.s=t.s+1;if(!vis[s.a][s.b][s.c])vis[s.a][s.b][s.c]=true,q.push(s);}if(t.c!=0)        //处理第三个瓶{if(t.c>a-t.a)s.a=a,s.b=t.b,s.c=t.c-(a-t.a),s.s=t.s+1;elses.a=t.a+t.c,s.b=t.b,s.c=0,s.s=t.s+1;if(!vis[s.a][s.b][s.c])vis[s.a][s.b][s.c]=true,q.push(s);if(t.c>b-t.b)s.a=t.a,s.c=t.c-(b-t.b),s.b=b,s.s=t.s+1;elses.c=0,s.a=t.a,s.b=t.b+t.c,s.s=t.s+1;if(!vis[s.a][s.b][s.c])vis[s.a][s.b][s.c]=true,q.push(s);}}return false;}int main(){int a,b,c,n;while(scanf("%d%d%d",&a,&b,&c)==3 && a+b+c){if(a&1)             //奇数不能平分puts("NO");else if(bfs(a,b,c,n))printf("%d\n",n);elseputs("NO");}return 0;}


0 0