zoukankan      html  css  js  c++  java
  • 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中的水倒完;

  • 相关阅读:
    ArrayList和LinkedList的底层代码实现思想
    ArrayList(顺序表)和LinkedList(链表)的区别联系,优劣取舍问题
    【AR】增强现实安卓编程
    【报错】"The constructor Notification(int, CharSequence, long) is deprecated
    【gradle报错】error: package org.apache.http does not exist
    【安卓面试题】多线程下载怎么实现?断点续传怎么实现?
    【安卓面试题】在一个Activity启动另一个Activity和在Service中启动一个Activity有什么区别
    java.lang.IllegalArgumentException: Service Intent must be explicit: Intent
    【Android Studio 小技巧】一键查看文件方法结构目录File Structure
    【安卓面试题】使用SQLiteOpenHelper的getReadableDatabase()获得的数据库能不能,做写的操作
  • 原文地址:https://www.cnblogs.com/1314wamm/p/5656031.html
Copyright © 2011-2022 走看看