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
2
2 3 4 2
96 97 199 62
Sample Output
2 2
9859 62
题意大概是三个杯子,第三个杯子有水,其他两个没水,然后给个目标,问你能不能把水倒来倒去得到那个目标,如果能输出最少需要的到水量,如果不能则输出比目标小的最大能到达的状态。
1.显然BFS,但是要求的不是最小的操作次数,而是最小的到水量,所以还需要优先队列。
2.记录的状态其实是n^2,总水量是确定的,前两个杯子里的水知道了,那第三个就确定了,所以说只需要开个二维数组来记录状态。
3.开始写的很乱,其实是没有正确理解优先队列,因为是按到水量从小到大排序的,那么如果这个状态还没到过,队列顶部取出的肯定是最优的,(后面的到水量都比顶部的大,如果在通过后面的状态达到当前,则一定小于这个状态,所以当顶部取出的状态是目标时,即可break;)
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<queue>
#define INF 1<<30
using namespace std;
struct node{
int a[3],k;
bool operator < (const node t) const {
return t.k>k;
}
};
int res[207],m[207][207];
int main()
{
int ci,i,j,b[5],k,kk;
node t,tt;
cin>>ci;
while(ci--)
{
for(i=0;i<205;i++)
{
for(j=0;j<205;j++)
m[i][j]=INF;
}
for(i=0;i<205;i++)
res[i]=INF;
priority_queue<node> pq;
cin>>b[0]>>b[1]>>b[2]>>k;
res[0]=res[b[2]]=0;
t.a[0]=t.a[1]=t.k=0;t.a[2]=b[2];
pq.push(t);
while(!pq.empty())
{
t=pq.top();pq.pop();
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
tt.a[0]=t.a[0],tt.a[1]=t.a[1],tt.a[2]=t.a[2],tt.k=t.k;
if(i==j) continue;
tt.a[j]=min(b[j],t.a[j]+t.a[i]);
tt.a[i]=max(0,t.a[i]-(tt.a[j]-t.a[j]));
tt.k=t.k+t.a[i]-tt.a[i];
if(res[tt.a[0]]>tt.k||res[tt.a[1]]>tt.k||res[tt.a[2]]>tt.k||m[tt.a[0]][tt.a[1]]>tt.k) {
if(res[tt.a[0]]>tt.k) res[tt.a[0]]=tt.k;
if(res[tt.a[1]]>tt.k) res[tt.a[1]]=tt.k;
if(res[tt.a[2]]>tt.k) res[tt.a[2]]=tt.k;
pq.push(tt);
if(m[tt.a[0]][tt.a[1]]>tt.k)
m[tt.a[0]][tt.a[1]]=tt.k;
}
}
}
}
while(res[k--]==INF);
cout<<res[k+1]<<' '<<k+1<<endl;
}
}