• J


    - 题目大意

        有三个已知体积但不知刻度的杯子,前两个杯子中初始时没有水,第三个装满水,问是否可以倒出d升水,如果倒不出,则倒出一个最大的d’,使得d’<=d,并且在这个过程中要求总倒水量最少。

    - 解题思路

        可以用DFS加上优先队列来解决,以前两个杯子中的水量作为标记状态。只不过这次不是要求的最求最少步数,而是要求最少倒水量即可。

    - 代码

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstring>
    #include<stack>
    #include<queue>
    using namespace std;
    int maps[500][500];
    int cnt[500];
    struct Edge
    {
        int m[3],sum;
        Edge(int a,int b,int c,int s)
        {
            m[0]=a,m[1]=b,m[2]=c,sum=s;
        }
        bool operator <(const Edge &rhs)const{
           return sum>rhs.sum;
         }
    };
    
    void bfs(int a,int b,int c,int d)
    {
        int num[3]={a,b,c};
        priority_queue<Edge>q;
        memset(maps,0,sizeof(maps));
        memset(cnt,-1,sizeof(cnt));
        maps[0][0]=1;
        q.push(Edge(0,0,c,0));
        while(!q.empty())
        {
            Edge u=q.top();
            q.pop();
            for(int i=0;i<3;i++)
            {
                if(cnt[u.m[i]]<0||u.sum<cnt[u.m[i]])
                    cnt[u.m[i]]=u.sum;
            }
            if(cnt[d]>=0)
                break;
            for(int i=0;i<3;i++)
            {
                if(u.m[i]==num[i])
                    continue;
                for(int j=0;j<3;j++)
                {
                    if(i==j||u.m[j]==0)
                        continue;
                    int mid=min(num[i],u.m[j]+u.m[i])-u.m[i];
                    Edge tmp=u;
                    tmp.sum+=mid;
                    tmp.m[i]+=mid;
                    tmp.m[j]-=mid;
                    if(!maps[tmp.m[0]][tmp.m[1]])
                    {
                        maps[tmp.m[0]][tmp.m[1]]=1;
                        q.push(tmp);
                    }
                }
            }
        }
        while(d>=0)
        {
            if(cnt[d]>=0)
              {
                  printf("%d %d
    ",cnt[d],d);
                  return;
        }
        --d;
        }
    }
    
    int main()
    {
        int a,b,c,d;
        int n;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            bfs(a,b,c,d);
        }
        return 0;
    }
    

      

  • 相关阅读:
    C#中的委托,匿名方法和Lambda表达式
    Java 8 Lambda表达式探险
    Lambda表达式有何用处?如何使用?
    有参数的程序,可以被调用
    怎样用VB编写.DLL动态链接库文件
    Oracle 存储过程包
    EB(存储单位)
    排序之快速排序(上)
    排序之冒泡排序
    排序之堆排序
  • 原文地址:https://www.cnblogs.com/alpacadh/p/8523858.html
Copyright © 2020-2023  润新知