zoukankan      html  css  js  c++  java
  • [UVA 10603]Fill

    这就是一道小学奥数倒水题(滑稽)

    言归正传,首先注意到数据范围很小,只有200,那么可以把三个杯子里的水量作为一个状态进行暴力bfs,显然水的总量一定,只要知道前两个杯子有多少水这个状态就确定了,也就是说状态最多200x200种,很小的。

    再考虑下贪心,到某个杯子水量为d的最小倒水量一定由前一个状态倒水量最小值搜索过来的,所以用一个优先队列存状态,按倒水量建个小根堆。

    最后如果实现不了某个杯子水量为d,还需要找到一个最接近的。于是我们可以用一个ans数组存储当一个杯子水量为i时的最小值,那么到不了d的话只需要不断向下找ans数组总会有这样一个d被更新。

    参考代码

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #define inf 1e9
    using namespace std;
    struct pos
    {
        int v[4];
        int sum;
        bool operator < (const pos &a) const
        {
            return sum > a.sum;
        }
    };
    int v[5],d,ans[210];
    bool vis[210][210][210];
    void bfs() 
    {
        memset(vis,0,sizeof(vis));
        memset(ans,-1,sizeof(ans));
        priority_queue<pos>q;
        pos top,node;
        top.v[1] = top.v[2] = 0;
        top.v[3] = v[3];
        top.sum = 0;
        vis[0][0][v[3]] = 1;
        q.push(top);
        while(q.size())
        {
            top = q.top();
            q.pop();
            for(int i = 1;i <= 3;i++)
            {
                if(ans[top.v[i]] < 0 || ans[top.v[i]] > top.sum) ans[top.v[i]] = top.sum;
            }
            if(ans[d] > 0) return;
            for(int i = 1;i <= 3;i++)
            {
                for(int j = 1;j <= 3;j++)
                {    
                    if(i == j) continue;     
                    if(!top.v[j]) continue;    
                    pos tmp;
                    if(top.v[j] + top.v[i] > v[i])
                    {
                        tmp.v[i] = v[i];
                        tmp.v[j] = top.v[j] + top.v[i] - v[i];
                        tmp.v[6 - i - j] = top.v[6 - i - j];
                        tmp.sum = top.sum + v[i] - top.v[i];
                    }
                    else
                    {
                        tmp.v[i] = top.v[i] + top.v[j];
                        tmp.v[j] = 0;
                        tmp.v[6 - i - j] = top.v[6 - i - j];  
                        tmp.sum = top.sum + top.v[j];
                    }
                    if(!vis[tmp.v[1]][tmp.v[2]][tmp.v[3]])
                    {
                        vis[tmp.v[1]][tmp.v[2]][tmp.v[3]] = 1;
                        q.push(tmp);
                    }
                }
            }
        }
        return;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d %d %d %d",&v[1],&v[2],&v[3],&d);
            bfs();
            while(ans[d] == -1) d--;
            printf("%d %d
    ",ans[d],d);
        }
        return 0;
    }
  • 相关阅读:
    面向对象:类的基础
    Apache:dbutils 开源JDBC工具类库
    JDBCToolsV3 :DAO
    JDBCToolsV2:利用ThreadLocal保证当前线程操作同一个数据库连接对象。
    JDBC: ThreadLocal 类
    JDBCTools 第一个版本
    数据库连接池
    JDBC:处理事务
    应变片安装
    博客园 PT100 烟温隔离板资料
  • 原文地址:https://www.cnblogs.com/lijilai-oi/p/10737750.html
Copyright © 2011-2022 走看看