Fill

Description

There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not greater than 200). The first and the second jug are initially empty, while the third

is completely filled with water. It is allowed to pour water from one jug into another until either the first one is empty or the second one is full. This operation can be performed zero, one or more times.

You are to write a program that computes the least total amount of water that needs to be poured; so that at least one of the jugs contains exactly d liters of water (d is a positive integer not greater than 200). If it is not
possible to measure d liters this way your program should find a smaller amount of water d‘ < d which is closest to d and for which d‘ liters could be produced. When d‘ is found, your program should compute the least total amount of poured water needed to
produce d‘ liters in at least one of the jugs.

Input

The first line of input contains the number of test cases. In the next T lines, T test cases follow. Each test case is given in one line of input containing four space separated integers - a, b, c and d.

Output

The output consists of two integers separated by a single space. The first integer equals the least total amount (the sum of all waters you pour from one jug to another) of poured water. The second integer equals d, if d liters
of water could be produced by such transformations, or equals the closest smaller value d‘ that your program has found.


Sample Input


Sample Output


2

2 3 4 2

96 97 199 62


2 2

9859 62

题意:给你三个杯子a,b,c;其中前两个是空的,第三个是满的;给的测试数据是每个杯子的容量,第四个是要求得的水的体积;若得不到,则取最接近的值;

输出时第一个数是水的转移量;第二个数是你所能得到的最接近所需要水的值;每次倒水每个杯子的状态都会变化,那么便可以考虑用广搜做;

eg:2 3 4 2

从第三个杯子倒水到第一个杯子;知道第一个杯子满了或者第三个杯子空了时在结束;     这是便得到所需要水的量  2 ;   其中水的转移量是 2 ;

那么便输出   2  2;

标程:

<span style="font-size:14px;"># include <cstdio>
# include <queue>
# include <cstring>
# include <iostream>
using namespace std;

const int Max=202;
int dist[Max][Max],ans[Max],cup[3];    //dist数组标记到这个状态使用了多少水;ans[ i ]用来记住得到 i 的水最佳转移量;

struct node
{
    int v[3],dist;
    bool operator < (const node &n) const
    {
        return dist > n.dist;
    }
};

void updata(const node &u)    //更新状态的水转移量;
{
    for(int i=0;i<3;i++)
    {
        int d=u.v[i];
        if(ans[d]<0||ans[d]>u.dist)    ans[d]=u.dist;
    }
}

void solve(int a,int b,int c,int d)
{
    cup[0]=a,cup[1]=b,cup[2]=c;    //记住每个杯子的最大容量;
    node start;
    int i,j;
    start.v[0]=start.v[1]=0;   start.v[2]=c;   start.dist=0;
    memset(dist,-1,sizeof(dist));
    memset(ans,-1,sizeof(ans));
    priority_queue <node> q;
    q.push(start);
    dist[start.v[0]][start.v[1]]=0;
    while(!q.empty())
    {
        node u;
        u=q.top();   q.pop();
        updata(u);
        for(i=0;i<3;i++)
            for(j=0;j<3;j++)
            if(i!=j)
            {
                if(u.v[i]==0||u.v[j]==cup[j])    continue;    //能不倒水 || 能不能盛水;
                int amost = cup[j] < u.v[i] + u.v[j] ? cup[j]-u.v[j] : u.v[i];   //求出转移量;
                node n;
                memcpy(&n,&u,sizeof(u));
                n.dist+=amost;     //更新新的状态;
                n.v[i]-=amost;
                n.v[j]+=amost;
                int &D = dist[n.v[0]][n.v[1]];
                if(D < 0 || D > n.dist)    //判断是不是出现过 || 用水量小于上一种情况,便重新入队列;
                {
                    D = n.dist;
                    q.push(n);
                }
            }
    }
    while(d>=0)     //寻找最接近的值;
    {
        if(ans[d] < 0)    d--;
        else
        {
            cout<<ans[d]<<' '<<d<<"\n";
            return ;
        }
    }
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        solve(a,b,c,d);
    }
    return 0;
}</span>
时间: 2024-10-17 01:12:51

Fill的相关文章

UVA10603 Fill

优秀的程序员一定是CV大师.能CV则CV的做法,可以省去许多编码和测试的时间.但是,如果出现小错误的话,找起来一样的费时. 问题链接:UVA10603 Fill. 题意简述:有三个壶,容量分别是a.b和c升,开始时候第1个和第2个壶是空的,第3个壶是满水的.可以把一个壶的水倒入另一个壶中,直到倒空或将另外一个壶倒满.输入a.b.c和d,计算最少的倒水量,使得其中一个壶里有d升水.如果不能倒出d升水的话,那么找一个最大的d'<d.输出倒水量和d,如果找不到的话输出倒水量和d'. 问题分析:将<a

【R】数据导入读取read.table函数详解,如何读取不规则的数据(fill=T)

函数 read.table 是读取矩形格子状数据最为便利的方式.因为实际可能遇到的情况比较多,所以预设了一些函数.这些函数调用了 read.table 但改变了它的一些默认参数.  注意,read.table 不是一种有效地读大数值矩阵的方法:见下面的 scan 函数. 一些需要考虑到问题是: 编码问题 如果文件中包含非-ASCII字符字段,要确保以正确的编码方式读取.这是在UTF-8的本地系统里面读取Latin-1文件的一个主要问题.此时,可以如下处理 read.table(file("fil

Python3 Tkinter基础 Scrollbar pack(side,fill) 在一个窗体中创建一个靠右的 充满Y轴的垂直滚动条

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: from tkinter import * root=Tk() scroll=Scrollbar(root) scroll.pack(side=RIGHT,fill=Y) mainloop() result: --------------------------

fill函数和fill_n函数

fill_n函数的作用是:给你一个起始点,然后再给你一个数值count和val.把从起始点开始依次赋予count个元素val的值. 注意: 不能在没有元素的空容器上调用fill_n函数 列子:     fill函数的作用是:将一个区间的元素都赋予val值.函数参数:fill(first,last,val);//first为容器的首迭代器,last为容器的末迭代器,val为将要替换的值. 例题:给你n个数,然后输入一些操作:start,end,paint.表示从start到end都赋予paint的

自己写的SqlHelper,提示在调用&quot;Fill&quot;前,SelectCommand 属性尚未初始化.错误

namespace 操作数据{    class SqlHelper    {        public DataSet SqlTODs(string cmdstring)        {            DataSet ds = new DataSet();            try            {                string sqlstring = System.Configuration.ConfigurationManager.Connection

STL算法find,find_if,find_if_not,sort,fill,for_each,count,adjacent_find,random_shuffle,prev_permutation

 1find查找 #include<iostream> #include<vector> #include<algorithm> #include<list> #include<set> #include<string> usingnamespacestd; voidmain() { vector<int>myv; myv.push_back(1); myv.push_back(2); myv.push_back(3)

UVA 10603 Fill(正确代码虽然很搓,网上许多代码都不能AC)

在做用户查找时 因为要把查找的结果动态加载和显示,所以,那些html元素要由Ajax动态生成.用户打开查找界面时,有系统推荐的用户,而当用户按条件查找后,查找的结果动态加载和显示.所以考虑到用js来搞. 这个for循环就是移除已有的表单.然后根据Ajax请求过来的数据,动态生成新的表单对象.一定要注意j变量从大往小循环,否则,删除div元素后会引起serchResultLenth=serchResult.children.length;长度的变化(这个问题摸索了好久,才搞定,切记) for(va

node.js中的buffer.fill

buffer.fill(value, [offset], [end]) 接收参数: value           将要填充的数据 offet           填充数据的开始位置,不指定默认为 0 end            填充数据的结束位置,不指定默认为 buffer 的长度.

fill与memset的区别

fill 的头文件是<iostream> 命名空间是std: 在memset(a,0(-1),sizeof(a))全部初值定为0或-1时两者是没有多大区别; 但是在初值为其他值得时候就不同了 fill是把那一块单元赋成指定的值,而memset是按字节填充的:

PAT 1033. To Fill or Not to Fill (25)(贪心)

解题思路: 其实题目本身不难,难就难在对贪心策略的选取 在每一个加油点应该做这样的判断: 1.首先计算从本加油点做多可能达到的加油点 2.如果有可达加油点的话: 2.1 寻找有无比当前加油点油价便宜的加油点,如果有的话就跑到该便宜的加油点,油量加到支持到该加油点即可 2.2 如果没有比当前加油点更便宜的加油点的话,又分两种情况: 2.2.1.如果本次加油可能直接到终点,就加可以到达终点的油量 2.2.2.否则的话,加满 3.如果没有可达加油点的话: 3.1 看是否可以直接达到终点 3.2 不能达