Type: Implicit Graph Search
Original question:
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 med 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 shocould find a smaller amount of water d' <d which is closest to d and for which d' liters cocould be produced. when d 'is found, your program shocould 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 cocould 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
Question:
There are three cups. Their capacities are a, B, and c respectively. In the initial state, the first and second cups are empty, and the third cups are full of water. You can pour the water from one cup into another. Of course, when the poured cup is full or the poured cup is full, you cannot continue to pour it.
Your task is to write a program to calculate the least amount of inverted water, so that d is in one of the cups. If you cannot pour out d to raise the water, find a d' <d, so that d' is closest to d.
Analysis and Summary:
Because there are three water cups, you can get a state (v1, v2, v3) based on the water volume of each cup v1, v2, and v3 );
To facilitate status transfer of dfs search, you can use two three-dimensional arrays volume [3] and state [3] to indicate the capacity and status of the three cups. Then there will be the action of pouring water, from 1st cups into the second and second, from 2nd into the first and third ...... So we can use two for loops to traverse all the reverse water solutions.
Then pay attention to some conditions where water cannot be poured. For example, if the cup to be poured is empty and the target cup is full, the water will not be poured.
Solution Report on the Internet: Using bfs
[Cpp]
// Dfs, Implicit Graph Search
// Time: 0.072 s (ultraviolet)
# Include <iostream>
# Include <cstdio>
# Include <cstring>
Using namespace std;
Int d, volume [3], state [3], minVolume, d1;
Bool flag, vis [205] [205] [205];
Void search (int tot ){
// Update the status of the result. Note that
For (int I = 0; I <3; ++ I ){
If (state [I] & state [I] = d ){
D1 = d;
If (! Flag) minVolume = tot; // if the first occurrence is d, the current total tot is directly assigned to minVolume.
Else if (tot <minVolume) minVolume = tot; // in the future, if the tot is less than minVolume, it will be updated.
Flag = true; // The flag indicates that the value is d.
}
Else if (! Flag & state [I] & state [I] <d) {// Note :! Flag indicates that the following statements are executed only when d is not found.
If (d-state [I] <d1 ){
D1 = d-state [I];
MinVolume = tot;
}
Else if (d-state [I] = d1 & tot <minVolume)
MinVolume = tot;
}
}
For (int I = 0; I <3; ++ I ){
For (int j = 0; j <3; ++ j) if (I! = J & state [I] & state [j]! = Volume [j]) {
Int add;
Int tmp_ I = state [I], tmp_j = state [j]; // backup, to be restored after backtracking
If (state [I]> = volume [j]-state [j]) {// if the pouring water is greater than or equal to the remaining capacity of the inverted cup, it will be full
Add = volume [j]-state [j];
State [I]-= add;
State [j] = volume [j];
}
Else {// otherwise, all are switched to the target cup
State [j] + = state [I];
Add = state [I];
State [I] = 0;
}
If (! Vis [state [0] [state [1] [state [2]) {
Vis [state [0] [state [1] [state [2] = true;
Search (tot + add );
Vis [state [0] [state [1] [state [2] = false; // trace back to restore the status
}
State [I] = tmp_ I; // trace back to restore the status
State [j] = tmp_j;
}
}
}
Int main (){
Int T;
Scanf ("% d", & T );
While (T --){
Scanf ("% d", & volume [0], & volume [1], & volume [2], & d );
State [0] = 0, state [1] = 0, state [2] = volume [2];
Memset (vis, 0, sizeof (vis ));
Vis [0] [0] [volume [2] = true;
Flag = false;
MinVolume = d1 = 1000000;
Search (0); www.2cto.com
If (flag) printf ("% d \ n", minVolume, d1 );
Else printf ("% d \ n", minVolume, d-d1 );
}
Return 0;
}
Author: shuangde800