搜索练习10/hdu.edu.cn/problem1495 非常可乐,bfs+回溯

来源:互联网 发布:知乎广州it培训机构 编辑:程序博客网 时间:2024/06/07 19:00

http://acm.hdu.edu.cn/showproblem.php?pid=1495

非常可乐

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14272    Accepted Submission(s): 5712


Problem Description
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
 

Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
 

Output
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
 

Sample Input
7 4 34 1 30 0 0
 

Sample Output
NO3

第一次做到水问题,代码有点长,不过很好理解。都是根据自己想法打的代码。

题意就不多说,都懂的。题意有一点就是:两杯水相等并且另一杯水量为0才行。

思路:只有3个杯子,1>2,1>3,2>3,2>1,2>3,3>1;">"表示谁往谁水。总共6种情况。bfs解法。

附上我的AC代码(内存1.6MB,时间46ms,长度4755):觉得这道题我应该练一下回溯的(有好多题需要输出过程的,很有必要写一下),所以,我就画蛇添足,写了回溯,哈哈,不好意思,代码有点长,但大部分是重复的。

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<vector>#include<map>#include<string>#define LL long long#define eps 1e-8using namespace std;const int mod = 1e7+7;const int INF = 1e8;const int inf = 0x3f3f3f3f;const int maxx = 100100;const int N = 1050;map<int,int>ma;//map标记int n,m,k;struct node{    int x,y,z,step;//    int a1[100],a2[100],a3[100];//回溯,存过程};node p1,p2;int bfs(){    queue<node>q;    p1.x=n,p1.y=0,p1.z=0,p1.step=0;    ma[p1.x*1e6+p1.y*1e3+p1.z]=1;    q.push(p1);    while(!q.empty())    {        p1=q.front();        q.pop();        if(p1.y!=m&&p1.x)//1>2:1往2倒水,下同。        {            p2.step=p1.step+1;            p2.z=p1.z;            if(p1.y+p1.x>=m)            {                p2.y=m;                p2.x=p1.y+p1.x-m;            }            else            {                p2.y=p1.y+p1.x;                p2.x=0;            }            if(!ma[p2.x*1e6+p2.y*1e3+p2.z])            {//                p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z;                ma[p2.x*1e6+p2.y*1e3+p2.z]=1;                if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y))                    return p2.step;                q.push(p2);            }        }        if(p1.z!=k&&p1.x)//1>3        {            p2.y=p1.y;            p2.step=p1.step+1;            if(p1.z+p1.x>=k)            {                p2.z=k;                p2.x=p1.z+p1.x-k;            }            else            {                p2.z=p1.z+p1.x;                p2.x=0;            }            if(!ma[p2.x*1e6+p2.y*1e3+p2.z])            {//                p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z;                ma[p2.x*1e6+p2.y*1e3+p2.z]=1;                if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y))                    return p2.step;                q.push(p2);            }        }        if(p1.z!=k&&p1.y)//2>3        {            p2.x=p1.x;            p2.step=p1.step+1;            if(p1.y+p1.z>=k)            {                p2.z=k;                p2.y=p1.y+p1.z-k;            }            else            {                p2.z=p1.y+p1.z;                p2.y=0;            }            if(!ma[p2.x*1e6+p2.y*1e3+p2.z])            {//                p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z;                ma[p2.x*1e6+p2.y*1e3+p2.z]=1;                if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y))                    return p2.step;                q.push(p2);            }        }        if(p1.y)//2>1        {            p2.z=p1.z;            p2.step=p1.step+1;            p2.x=p1.y+p1.x;            p2.y=0;            if(!ma[p2.x*1e6+p2.y*1e3+p2.z])            {//                p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z;                ma[p2.x*1e6+p2.y*1e3+p2.z]=1;                if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y))                    return p2.step;                q.push(p2);            }        }        if(p1.z)//3>1        {            p2.y=p1.y;            p2.step=p1.step+1;            p2.x=p1.z+p1.x;            p2.z=0;            if(!ma[p2.x*1e6+p2.y*1e3+p2.z])            {//                p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z;                if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y))                    return p2.step;                ma[p2.x*1e6+p2.y*1e3+p2.z]=1;                q.push(p2);            }        }        if(p1.y!=m&&p1.z)//3>2        {            p2.x=p1.x;            p2.step=p1.step+1;            if(p1.y+p1.z>=m)            {                p2.y=m;                p2.z=p1.y+p1.z-m;            }            else            {                p2.y=p1.y+p1.z;                p2.z=0;            }            if(!ma[p2.x*1e6+p2.y*1e3+p2.z])            {//                p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z;                if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y))                    return p2.step;                ma[p2.x*1e6+p2.y*1e3+p2.z]=1;                q.push(p2);            }        }    }    return -1;}int main(){    while(~scanf("%d%d%d",&n,&m,&k))    {        if(n==0&&m==0&&k==0)            break;        ma.clear();        int ans=bfs();        if(ans==-1)            printf("NO\n");        else            printf("%d\n",ans);//            for(int i=1;i<=p2.step;i++)//            printf("%d %d %d\n",p2.a1[i],p2.a2[i],p2.a3[i]);    }}

因为自己代码又丑又长,再附上其他人的高级代码(内存6MB,时间748ms,长度1781):

# include <stdio.h># include <queue># include <string.h>using namespace std;#define max 105struct node{    int cpu[3];//用数组方便对容器进行操作     int step;};int full[3];//设置容器的容量 int dir[6][2] = {{0,1}, {0,2}, {1,0}, {1,2}, {2,0}, {2,1}};int v[max][max][max] = {0};//标记数组,判断是否重复 void turn(int &a, int &b, int fullb)//将a的水倒入b {    if( a+b < fullb)    {        b += a;        a = 0;    }    else    {        a -= (fullb - b);        b = fullb;    }}int PAN(node s)//因为三个杯子互相倒,任意两个杯子都有可能存放一半的水 {    if(s.cpu[0] + s.cpu[1] == full[0] && s.cpu[0] == s.cpu[1])    return 1;    if(s.cpu[0] + s.cpu[2] == full[0] && s.cpu[0] == s.cpu[2])    return 1;    if(s.cpu[1] + s.cpu[2] == full[0] && s.cpu[1] == s.cpu[2])    return 1;       return 0;   }int BFS(node s){    queue<node>Q;    Q.push(s);    node q;    while(Q.size())    {        s = Q.front();        Q.pop();        if(PAN(s))          return s.step;        for(int i = 0; i<6; i++)        {            q = s;            turn(q.cpu[dir[i][0]], q.cpu[dir[i][1]], full[dir[i][1]]);            if(v[ q.cpu[0] ][q.cpu[1]][q.cpu[2]] == 0)            {                q.step+=1;            v[ q.cpu[0] ][q.cpu[1]][q.cpu[2]] = 1;                Q.push(q);            }        }    }    return -1;}int main(void){    node s;    while(scanf("%d%d%d",&full[0], &full[1], &full[2]), full[0] + full[1]+full[2])    {        s.cpu[0] = full[0];        s.step = s.cpu[1] = s.cpu[2] = 0;        memset(v, 0, sizeof(v));        int ans = BFS(s);        if(ans == -1)        printf("NO\n");        else        printf("%d\n",ans);    }    return 0;}









0 0
原创粉丝点击