POJ 3414 get the desired capacity BFS

Source: Internet
Author: User


The question is: it is legal to give you two fixed-capacity beaker with A capacity and B respectively.

1. Fill Up With A and get it from the water source

2. Full B

3. Pour A to B. After B is finished, B is full, or A is empty.

4. Pour B to A. After it is finished, A is full, or B is empty.

5. Clear

6. Clear B


The minimum steps can be obtained from the first two empty cups to obtain the water with a volume of C, where the water with a capacity of C can be placed in any container.

Sample Input

3 5 4
Sample Output

6
FILL (2)
POUR (2, 1)
DROP (1)
POUR (2, 1)
FILL (2)
POUR (2, 1)


Analysis: the classification of this question is BFS, but I haven't figured out how to BFS for a long time. I read some tips in discussion to see all the insights.

In the BFS process, the current status is two numbers: ca and cb. It indicates that there is water ca in the a beaker, And there is water cb in the B beaker.

Because there are only six options in the next step, we can enumerate all these six cases. For example, when the weights are enumerated to stepi, if the operations in this step occur, the status has been reached, we will not put the new status into the queue,

Otherwise, it is put into the queue as a new status.


We need to record the path, so we need to keep the status before each status, and also how many steps have taken to save it to the current status.

Therefore, each status has the following values:

1. Capacity of two beaker 2. Previous status 3. operation performed in the current status Step 4 to this status.


The Code is as follows:

[Cpp]
# Include <stdio. h>
# Include <memory. h>
 
# Define MAX_NUM 101
# Define MAX_Q MAX_NUM * MAX_NUM
 
Enum OPERATION
{
FILL1 = 0, FILL2, POUR12, POUR21, DROP1, DROP2, NONE
};
 
Struct Step
{
Int liter1;
Int liter2;
Int stepID;
 
OPERATION operation;
Int previous;
 
Step ()
{
 
}
Step (int l1, int l2, int step, OPERATION op, int previous)
{
Liter1 = l1;
Liter2 = l2;
StepID = step;
Operation = op;
This-> previous = previous;
 
}
};
 
Struct Queue
{
Step steps [MAX_Q];
Int front;
Int rear;
 
 
Void ini ()
{
Memset (steps, 0, sizeof (steps ));
Front = rear = 0;
}
 
Void push (int l1, int l2, int step, int privous, OPERATION op)
{
Steps [rear ++] = Step (l1, l2, step, op, privous );
}
 
 
};
 
Bool visit [MAX_NUM] [MAX_NUM];
Queue q;
 
Void PrintPath (int I)
{
If (I =-1)
{
Return;
}
PrintPath (q. steps [I]. previous );
 
Switch (q. steps [I]. operation)
{
Case FILL1:
 
Printf ("FILL (1) \ n ");
Break;
 
Case FILL2:
Printf ("FILL (2) \ n ");
Break;
 
Case POUR12:
Printf ("POUR (1, 2) \ n ");
Break;
 
Case POUR21:
Printf ("POUR (2, 1) \ n ");
Break;
 
Case DROP1:
Printf ("DROP (1) \ n ");
Break;
 
Case DROP2:
Printf ("DROP (2) \ n ");
Break;
}
}
Void BFS (int a, int B, int c)
{
Q. ini ();
Q. push (0, 0, 0,-1, NONE );
Visit [0] [0] = true;
Step nxt, current;
While (q. rear> q. front)
{
Current = q. steps [q. front ++];
If (current. liter1 = c | current. liter2 = c)
{
Break;
}
OPERATION iOp;
For (int I = 0; I <6; I ++)
{
IOp = (OPERATION) I;
Nxt = current;
Switch (iOp)
{
Case FILL1:
{
// Fill glass
If (! Visit [a] [nxt. liter2])
{
Q. push (a, nxt. liter2, current. stepID + 1, q. front-1, FILL1 );
Visit [a] [nxt. liter2] = true;
}
Break;
}
Case FILL2:
{
If (! Visit [nxt. liter1] [B])
{
Q. push (nxt. liter1, B, current. stepID + 1, q. front-1, FILL2 );
Visit [nxt. liter1] [B] = true;
}
Break;
}
Case POUR12:
{
Int newA = current. liter1;
Int newB = current. liter2;
If (newA + newB> B)
{
NewA = newA + newB-B;
NewB = B;
}
Else
{
NewB = newA + newB;
NewA = 0;

}
If (! Visit [newA] [newB])
{
Q. push (newA, newB, current. stepID + 1, q. front-1, POUR12 );
 
Visit [newA] [newB] = true;
}
Break;
}
Case POUR21:
{
Int newA = current. liter1;
Int newB = current. liter2;
 
If (newA + newB>)
{

NewB = newA + newB-;
NewA =;
}
Else
{
NewA = newA + newB;
NewB = 0;
}
 
If (! Visit [newA] [newB])
{
Q. push (newA, newB, current. stepID + 1, q. front-1, POUR21 );
 
Visit [newA] [newB] = true;
}
Break;
}
Case DROP1:
{
If (! Visit [0] [nxt. liter2])
{
Q. push (0, nxt. liter2, current. stepID + 1, q. front-1, DROP1 );
Visit [0] [nxt. liter2] = true;
}
Break;
}
Case DROP2:
{
If (! Visit [nxt. liter1] [0])
{
Q. push (nxt. liter1, 0, current. stepID + 1, q. front-1, DROP2 );
Visit [nxt. liter1] [0] = true;
}
Break;
}
}
}
}
If (q. front = q. rear)
{
Printf ("impossible \ n ");
}
Else
{
Printf ("% d \ n", q. steps [q. front-1]. stepID );
PrintPath (q. front-1 );
}
}
 
Int main ()
{
 
Int a, B, c;
 
While (scanf ("% d", & a, & B, & c )! = EOF)
{
Memset (visit, 0, sizeof (visit ));
BFS (a, B, c );
}
Return 0;
}

Several bugs were made during the compilation, making it impossible to call the SDK for half a day.
Bug1, when newA newB is assigned a value, the order is written incorrectly, ignoring the fact that the two values are dependent.

Bug2, at the end of the traversal, the front-1 is not written. In fact, when the front is finished last time, it is already-1.


Author: hopeztm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.