• UVA 10603 倒水问题


    题意:

    给定3个杯子的容量, 然后一开始第3个杯子水是满的, 求出最少倒多少升水才能让某个杯子有d 升水, 如果无法做到, 求出d',(d' < d 且尽量接近d)

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 200 + 7;
    struct node
    {
        int v[3], dist;
        bool operator < (const node& a) const
        {
            return dist > a.dist;
        }
    };
    int D[maxn];
    void update(node u)
    {
        for(int i = 0; i < 3; i++)
        {
            if(D[u.v[i]] == -1 || u.dist < D[u.v[i]]) //如果这个水量的距离没被标记过, 或者当前该水量的距离比记录距离小, 更新记录距离
                D[u.v[i]] = u.dist;
        }
    }
    void solve(int a, int b, int c, int d)
    {
        int cap[3];
        memset(D, -1 , sizeof(D));
        cap[0] = a, cap[1] = b, cap[2] = c;
    
        bool vis[maxn][maxn];
        memset(vis,0,sizeof(vis));
    
        priority_queue<node> q;
        node st;
        st.v[0] = st.v[1] = 0, st.v[2] = c,st.dist = 0;
        vis[0][0] = 1;
        q.push(st);
    
        while(!q.empty())
        {
            node u = q.top();
            update(u);
            if(D[d] > 0){//
                printf("%d %d
    ", D[d], d);
                return;
            }
            for(int i = 0; i < 3; i++)
            for(int j = 0; j < 3; j++)
            {
                if(i != j) // i pull j
                {
                    if(u.v[i] == 0 || u.v[j] == cap[j]) continue;
                    int amount = min(u.v[i] , cap[j] - u.v[j]);   //j full or i empty
    
                    node u2;
                    memcpy(&u2, &u, sizeof(u));
    
                    u2.v[i] -= amount , u2.v[j] += amount;
                    u2.dist += amount;
                    if(!vis[u2.v[0]][u2.v[1]]){
                        vis[u2.v[0]][u2.v[1]] = 1;
                        q.push(u2);
                    }
                }
            }
            q.pop();
        }
        for(;d>=0;){//找不到d, 往下找d' (题目规定d' < d)
            while( D[d]  == -1) d--;
            printf("%d %d
    ", D[d], d);
            return;
        }
    }
    int main()
    {
        int T, a, b, c, d;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d%d%d", &a, &b, &c, &d);
            solve(a,b,c,d);
        }
        return 0;
    }
  • 相关阅读:
    男子汉要响当当面对自己写出的程序
    北京天气变化,记下它
    面向对象的设计原则-类设计原则
    JSSCript打开X3,并设置IE窗口样式
    “做人做事”的信条
    工作角色的定位
    JS语法字典网友总结
    处理多个选择结果
    Jquery获得控件值的方法
    选择器
  • 原文地址:https://www.cnblogs.com/Jadon97/p/8317574.html
Copyright © 2020-2023  润新知