• HDU1495(bfs)


    非常可乐

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


    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 3
    4 1 3
    0 0 0
     
    Sample Output
    NO
    3

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int MAX=105;
    int s,n,m;
    struct node{
    int s,n,m,t;
    };
    int vis[MAX][MAX][MAX];
    int bfs(){
    node now,next;
    queue<node>q;
    while(!q.empty())
    q.pop();
    now.s=s;now.n=now.m=now.t=0;
    memset(vis,0,sizeof(vis));
    vis[s][0][0]=1;
    q.push(now);
    while(!q.empty()){
    now=q.front(),q.pop();
    if((now.n==now.m&&now.s==0)||(now.n==now.s&&now.m==0)||(now.s==now.m&&now.n==0))
    return now.t;
    int tmp;
    if( now.s!=0 ){
    if( now.n!=n ){
    tmp=min( now.s,n-now.n );
    next=now;
    next.t=now.t+1;
    next.s-=tmp;
    next.n+=tmp;
    if( vis[next.s][next.n][next.m]==0/*vis[ next ]==0*/ ){
    vis[next.s][next.n][next.m]=1;//vis[ next ]=1;
    q.push(next);
    }
    }
    if( now.m!=m ){
    tmp=min( now.s,m-now.m );
    next=now;
    next.t=now.t+1;
    next.s-=tmp;
    next.m+=tmp;
    if( vis[next.s][next.n][next.m]==0/*vis[ next ]==0*/ ){
    vis[next.s][next.n][next.m]=1;//vis[ next ]=1;
    q.push( next );
    }
    }
    }// 1 to (2 or 3)
    if(now.n!=0){
    tmp=now.n;
    next=now;
    next.t=now.t+1;
    next.s+=tmp;
    next.n=0;
    if( vis[next.s][next.n][next.m]==0/*vis[ next ]==0*/ ){
    vis[next.s][next.n][next.m]=1;//vis[ next ]=1;
    q.push( next );
    }
    if( now.m!=m ){
    tmp=min(m-now.m,now.n);
    next=now;
    next.t=now.t+1;
    next.m+=tmp;
    next.n-=tmp;
    if(vis[next.s][next.n][next.m]==0/*vis[ next ]==0*/){
    vis[next.s][next.n][next.m]=1;//vis[ next ]=1;
    q.push( next );
    }
    }
    }//2 to( 1 or 3 )
    if( now.m!=0 ){
    tmp=now.m;
    next=now;
    next.t=now.t+1;
    next.m=0;
    next.s+=tmp;
    if( vis[next.s][next.n][next.m]==0/*vis[ next ]==0*/ ){
    vis[next.s][next.n][next.m]=1;//vis[ next ]=1;
    q.push( next );
    }
    if( now.n!=n ){
    tmp=min( n-now.n,now.m );
    next=now;
    next.t=now.t+1;
    next.n+=tmp;
    next.m-=tmp;
    if( vis[next.s][next.n][next.m]==0/*vis[ next ]==0*/ ){
    vis[next.s][next.n][next.m]=1;//vis[ next ]=1;
    q.push( next );
    }
    }
    }
    }
    return -1;
    }
    int main(){
    while( scanf("%d%d%d",&s,&n,&m),s+n+m )
    {
    if( s%2==1 ){
    printf("NO ");
    continue;
    }
    if( n==m ){
    printf("1 ");
    continue;
    }
    int ans=bfs();
    if( ans!=-1 )
    printf("%d ",ans);
    else
    printf("NO ");
    }
    return 0;
    }

    这是一个经典的广搜题,开始我是用java编写的,但是总是写不对,后来询问了一下老师,老师说要拷贝now里面的数据再去倒;这个地方有几个小细节大家应该要注意。这里基本上采用了暴力列举,把六种情况列举了出来。先是从1倒到或2,把他们倒满,再是从2倒到3或者是1把2的中的水倒完。3倒到1或者2,把3中的水倒完;

  • 相关阅读:
    【2021-01-01】爱自己等于爱家人
    【2020-12-31】2020的收获与2021的挑战
    【2020-12-30】说别人辛苦,其实是自己辛苦
    【一句日历】2021年1月
    最大子序和
    判断子序列
    下载安装 ethereal
    6812. 【2020.10.05提高组模拟】战争
    6816. 【2020.10.06提高组模拟】随机的排列
    python 版本及pip安装相关
  • 原文地址:https://www.cnblogs.com/1314wamm/p/5656031.html
Copyright © 2020-2023  润新知