Question;
How to load water to C using only two containers
Analysis:
BFS questions, but to record the path, referAlgorithmIntroduction to the BFS algorithm (I refer to other people'sProgram).
Here is a brief summary: seeCodeText in
# Include <iostream>
# Include <queue>
# Include <cstring> using namespace STD;
# Define x 105
Int A, B, C;
Bool use [x] [x];
////// This structure records the AB volume and the total number of elapsed times.
Typedef struct
{
Int A; // The amount of water in
Int B; // The volume of B
Int step; // The total number of times
} Node;
///// This struct is used to record the undumped state.
Struct PN
{
Int PREA; // The amount of water a when not dumped
Int PREB; // The amount of B's water when not dumped
} PN;
Struct pn p [x] [x];
Void DFS (int x, int y)
{// X current A's water volume, and Y's current B's water volume
If (P [x] [Y]. PREA + P [x] [Y]. PREB! = 0)
DFS (P [x] [Y]. PREA, P [x] [Y]. PREB );
Int PX = P [x] [Y]. PREA; // The amount of water in the previous jar
Int py = P [x] [Y]. PREB; // The amount of water in the previous jar B
//// When the current water volume of A is full and the previous water volume is not full, and the water volume of B is not changed, it can only be fill
If (PX! = A & X = A & Y = Py)
{
Cout <"fill (1)" <Endl;
Return;
}
//// When B's current water volume is full and the previous water volume is not full, and a's water volume is not changed, it can only be fill B
If (PX = x & Y = B & py! = B)
{
Cout <"fill (2)" <Endl;
Return;
}
/// When the amount of water in a is still empty and the amount of water in B is not changed, it can only be drop1
If (! X & PX & Y = Py)
{
Cout <"drop (1)" <Endl;
Return;
}
/// When the water volume of B still exists and is empty, and the water volume of A does not change, it can only be drop2
If (! Y & py & PX = x)
{
Cout <"drop (2)" <Endl;
Return;
}
/// When the sum of the two sides is the same, it indicates that there is no full or irrigation, it can only be the reciprocal of AB.
If (PX + py = x + y)
{
If (! X | Y = B) // when a is null or B is full (note that a may fail over B)
Cout <"Pour (1, 2)" <Endl;
Else // likewise, vice versa
Cout <"Pour (2, 1)" <Endl;
Return;
}
}
Bool BFS ()
{
Memset (p, 0, sizeof (p ));
Memset (use, false, sizeof (use); // two values are cleared.
Node temp, temp1; // use two struct
Queue <node> NQ;
Temp. A = 0;
Temp. B = 0;
Temp. Step = 0;
Use [0] [0] = true;
NQ. Push (temp );
While (! NQ. Empty ())
{
Temp = NQ. Front ();
NQ. Pop ();
If (temp. A = c | temp. B = C) // when C is dumped
{
Cout <temp. Step <Endl;
DFS (temp. A, temp. B );
Return true;
}
/// // Start
Temp1.step = temp. Step + 1; // Add one at the start time
//// // Fill
Temp1.a =;
Temp1. B = temp. B;
If (! Use [temp1.a] [temp1. B]) // you have never used this flushing condition.
{
Use [temp1.a] [temp1. B] = true; // indicates that the water has been dumped.
P [temp1.a] [temp1. B]. PREA = temp. A; // records the water volume of the last time a is stored in the struct.
P [temp1.a] [temp1. B]. PREB = temp. B;
NQ. Push (temp1 );
}
/// // Fill B
Temp1.a = temp.;
Temp1. B = B;
If (! Use [temp1.a] [temp1. B])
{
Use [temp1.a] [temp1. B] = true;
P [temp1.a] [temp1. B]. PREA = temp.;
P [temp1.a] [temp1. B]. PREB = temp. B;
NQ. Push (temp1 );
}
/// // Drop
Temp1.a = 0;
Temp1. B = temp. B;
If (! Use [temp1.a] [temp1. B])
{
Use [temp1.a] [temp1. B] = true;
P [temp1.a] [temp1. B]. PREA = temp.;
P [temp1.a] [temp1. B]. PREB = temp. B;
NQ. Push (temp1 );
}
/// // Drop B
Temp1.a = temp.;
Temp1. B = 0;
If (! Use [temp1.a] [temp1. B])
{
Use [temp1.a] [temp1. B] = true;
P [temp1.a] [temp1. B]. PREA = temp.;
P [temp1.a] [temp1. B]. PREB = temp. B;
NQ. Push (temp1 );
}
//// // Pour A to B
Temp1.a = 0;
Temp1. B = temp. A + temp. B;
If (temp1. B> B) // note that a may fail over B, and B is full before B is finished.
{
Temp1.a = temp1. B-B;
Temp1. B = B;
}
If (! Use [temp1.a] [temp1. B])
{
Use [temp1.a] [temp1. B] = true;
P [temp1.a] [temp1. B]. PREA = temp.;
P [temp1.a] [temp1. B]. PREB = temp. B;
NQ. Push (temp1 );
}
//// // Pour B to
Temp1.a = temp. A + temp. B;
Temp1. B = 0;
If (temp1.a>)
{
Temp1. B = temp1.a-;
Temp1.a =;
}
If (! Use [temp1.a] [temp1. B])
{
Use [temp1.a] [temp1. B] = true;
P [temp1.a] [temp1. B]. PREA = temp.;
P [temp1.a] [temp1. B]. PREB = temp. B;
NQ. Push (temp1 );
}
}
Return false;
}
Int main ()
{
Freopen ("sum. In", "r", stdin );
Freopen ("sum. Out", "W", stdout );
While (CIN> A> B> C)
If (! BFS () // when not available
Cout <"impossible" <Endl;
Return 0;
}