zoukankan      html  css  js  c++  java
  • HDOJ 1495 非常可乐 【BFS】

    非常可乐

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


    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 <cstdio>
    #include <queue>  //用到了优先队列
    #include <cstring>
    #include <algorithm>
    const int M = 101;
    using namespace std;
    
    bool vis[101][101][101]; //标记状态
    struct node{
        int v[3];
        int step;
        bool operator < (const node &a) const{  
            return step > a.step;
        }
    };
    int hal, v[3];  //hal是一半,v数组是每一个杯子的容积
    
    bool match(node a){
        int ans = 0;
        for(int i = 0; i < 3; ++ i)
            if(a.v[i] == hal) ++ans;
        if(ans == 2) return 1;  //
        return 0;
    }
    
    int bfs(){
        memset(vis, 0, sizeof(vis));
        node st;
        st.v[0] = v[0]; st.v[1] = st.v[2] = 0;
        st.step = 0;
        priority_queue<node >q;
        q.push(st);
        vis[v[0]][0][0] = 1;
        if(match(st)) return st.step;
        while(!q.empty()){
            node temp = q.top();
            q.pop();
            for(int i = 0; i < 3; ++ i){  
                if(temp.v[i]){  //假设一个杯子有水,就让他往其它两个杯子倒水
                    for(int j = 1; j < 3; ++ j){
                        node cur = temp;
                        int w = (i+j)%3;
                        if(cur.v[w] < v[w]){  //倒的时候也分是不是满了,假设不满那么还须要推断能不能倒满还是不能倒满
                            if(cur.v[i] <= (v[w]-cur.v[w])){
                                cur.v[w] += cur.v[i]; cur.v[i] = 0;
                                if(match(cur)) return cur.step+1;
                            }
                            else {
                                cur.v[i] -= (v[w]-cur.v[w]);
                                cur.v[w] = v[w];
                                if(match(cur)) return cur.step+1;
                            }
                            if(!vis[cur.v[0]][cur.v[1]][cur.v[2]]){
                                    vis[cur.v[0]][cur.v[1]][cur.v[2]] = 1;
                                    cur.step++;
                                    q.push(cur);
                            }
                        }
                    }
                }
            }
        } 
        return -1;
    }
    
    int main(){
        while(scanf("%d%d%d", &v[0], &v[1], &v[2]), v[0]||v[1]||v[2]){
            if(v[0]&1){
                printf("NO
    ");
                continue;
            }
            else {
                hal = v[0]/2;
                int ans = bfs();
                if(ans >= 0) printf("%d
    ", ans);
                else printf("NO
    ");
            }
        }
        return 0;
    }


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    点击cell后 cell的背景不变,cell上的字体颜色发生改变的功能实现
    各种属性设置
    多列表 ,菜单
    正则表达式
    多个storyboard之间的跳转问题
    关于uicollectionview的个人学习
    uiscrollview的自动布局
    手动自动布局
    关于简单的跳转问题
    深入理解@class和#import的区别
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4815238.html
Copyright © 2011-2022 走看看