zoukankan      html  css  js  c++  java
  • UVA 10603_Fill

    题意:

    给定三个杯子容量,初始只有第三个杯子满,其余为空,求最少需要倒多少水才能让某一杯子中有d升水,如果不能达到,则小于d且尽量接近。

    分析:

    因为要求转移水量最少,所以采用优先级队列保存每次的状态,保证每次都是取出转移水量最少的点进行扩展。bfs求出杯中水达到d(接近d)时最少转移水量。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cmath>
    using namespace std;
    const int maxn=205, INF=0x3fffffff;
    struct Node{
        int n[3];
        int dist;
        bool operator < (const Node& a) const{
            return dist > a.dist;
        }
    };
    int vis[maxn][maxn], v[3], ans[maxn], d;
    void bfs()
    {
        memset(vis, 0, sizeof(vis));
        memset(ans, -1, sizeof(ans));
        priority_queue<Node>q;
        Node s;
        s.n[0]=0, s.n[1] = 0, s.n[2] = v[2];
        s.dist = 0;
        vis[0][0]=1;
        q.push(s);
        while(!q.empty()){
            Node t = q.top(); q.pop();
            for(int i = 0; i < 3; i++){
                if(ans[t.n[i]]<0) ans[t.n[i]] = t.dist;
                else   ans[t.n[i]] = min(ans[t.n[i]], t.dist);
            }
            if(ans[d]>=0) break;
            for(int i = 0; i < 3; i++){//i->j
                for(int j = 0; j < 3; j++){
                    if(i!=j){
                        if(t.n[i]==0||t.n[j]==v[j]) continue;
                        int t1 = t.n[i], t2 = t.n[j];
                        int temp = min(t1, v[j] - t2);
                        Node nt;
                        nt.n[i] = t1 - temp;
                        nt.n[j] = t2 + temp;
                        nt.n[3-i-j] = t.n[3-i-j];
                        nt.dist = t.dist + temp;
                        if(!vis[nt.n[0]][nt.n[1]]){//总水量一定,前两个杯子水量确定,第三个杯子水量也确定了
                            vis[nt.n[0]][nt.n[1]] = 1;
                            q.push(nt);
                        }
                    }
                }
            }
        }
        while(ans[d]<0) d--;
        printf("%d %d
    ",ans[d], d);
        return;
    }
    
    int main (void)
    {
        int T;scanf("%d",&T);
        while(T--){
            scanf("%d%d%d%d",&v[0],&v[1],&v[2],&d);
            bfs();
        }
        return 0;
    }
    
  • 相关阅读:
    dynamic不能使用扩展方法
    C# .Net 中字典Dictionary<TKey,TValue>泛型类 学习浅谈
    C# .Net List<T>中Remove()、RemoveAt()、RemoveRange()、RemoveAll()的区别,List<T>删除汇总
    Tomcat配置虚拟目录映射
    JAVA中令人疑惑的字符串
    JAVA控制台版斗地主
    JAVA学习路线
    vue安装(npm和cnpm)
    ThinkPad笔记本无法禁用触摸屏【亲测,有用】
    boostrap弹框之BootstrapDialog
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758839.html
Copyright © 2011-2022 走看看