1151. magic board Constraints
Time Limit: 1 secs, memory limit: 32 MB, special judge
Description
Questions are the same as question a. Here we expand the scope of data:N may exceed10.
Please carefully consider various situations.
Input
The input includes multiple magic boards to be solved. Each magic board is described in three lines.
N indicates the maximum number of allowed steps.
The second and third lines indicate the target status. The color ranges from 1 to 8 according to the shape of the magic board.
When N is equal to-1, the input ends.
Output
Output a line for each magic board to be solved.
The first is an integer m, indicating the number of steps you need to find the answer. After a few spaces, start from step 1 and perform step m operations (each step is A, B, or C) in sequence. There is no space between two adjacent operations.
Note: if it cannot be reached, M outputs-1.
Sample Input
45 8 7 64 1 2 338 7 6 51 2 3 4-1
Sample output
2 Ab1 a score: If M exceeds N or the given operation is incorrect, the score cannot be obtained.
Problem Source
Zsuacm team member
See Kanto expand: http://baike.baidu.com/view/437641.htm
# Include <iostream> # include <vector> # include <stack> # include <cstring> using namespace STD;/** specifies a status, in the specified step, a status array is defined through the, B, and C operations to reach the target State *. The header pointer FP points to the current parent node operation, and the RP * points to the subnode operation. When determining whether a subnode sequence is added: Judge again! * Hash is used to determine the weight, that is, a bool array is used to record whether a value is * already in the queue, that is, it has been accessed, the subscript of the bool array is calculated based on the x-forward expansion. It is a hash function. If the bool array is repeated, the operation is skipped and three * operations are performed on each parent node, when a qualified person enters the queue, the RP is moved back in sequence. After FP completes three operations, the FP ++ records the position of each status using the help column, that is to say, after you expand * through Kanto, you can know the number of rows in the status to locate the location immediately. * You can use an array to record the location access information. * The Kanto expansion method (a special hash function) * For example, for a sequence of 123, calculate the maximum number of 321 rows in its full arrangement. * If the first digit is 3, the second digit can be 1 or 2, and the second digit is 2*2! = Four numbers smaller than him, * then look at the second digit 2. If the number smaller than him is 1, then there is 1*1! = 1 so there are 4 + 1 = 5x321 small numbers, that is, it is 6th large. * /// Define a cube's struct typedef struct MF {int up; // The Cube's upstream number int down; // The Cube's downstream number char op; // obtain the cube int pre by this operation; // record the Cube's previous cube, that is, the subscript of the parent node in the three tree in the queue, this design is critical to the transformation of the result that outputs the shortest result to reach the target cube} MF; bool isvisited [50000]; // due to. up * 10000 + Mf. the 8-digit number is obtained after the data is down. Therefore, the number of all 8-digit numbers is 8 according to the Kento expansion formula! (A special hash function) int fact [9] = {1, 1, 2, 6, 24,120,720,504 0, 40320}; // 8! Factorial table, calculate the Expanded Value of the following conto // return value is the subscript in the array of all numbers whose number N records number N starting from 0: the number n is the nth largest in the Full Permutation. // expand the function in the conto column: index = A [n] * (n-1 )! + A [n-1] * (n-2 )! +... + A [I] * (I-1 )! +... + A [2] * 1! + A [1] * 0! [1] // where A is an integer and 0 <= A [I] <I (1 <= I <= N) int Cantor (long number) {int A [8]; int n = 0; int Index = 0; For (INT I = 7; I> = 0; I --) {// A [7,6, 5... 0] is a single digit, ten digits, hundred digits... A [I] = Number % 10; number/= 10;} For (INT I = 0; I <= 7; I ++) {// calculate a number smaller than a [I] For (Int J = I + 1; j <= 7; j ++) {if (a [I]> A [J]) n ++;} index + = N * fact [7-i]; n = 0;} Return Index ;} // compare whether the cube to be inserted already has bool CMP (vector <MF> & MFs, MF, char Op, int pre) {// The Cube does not exist in the queue. insert if (! Isvisited [Cantor (MF. up * 10000 + Mf. down)]) {// MF. up * 10000 + Mf. the down function makes the input of the Kanto function a unique eight-digit integer isvisited [Cantor (MF. up * 10000 + Mf. down)] = true; Mf. pre = pre; Mf. OP = op; MFs. push_back (MF); Return true;} return false;} // There are three operations in total, therefore, for the trigger tree // operate a 1234 8765-> 8765 1234, return the cube char OPA (MF, int pre, MF & result) after the operation through result reference) {int M = mf. up; int n = mf. down; Mf. up = N; Mf. down = m; Result = mf; result. pre = Pre; result. OP = 'a'; return 'a';} // operation B 1234 8765-> 4123 5876 char OPB (MF, int pre, MF & result) {int up_first = (MF. up % 10) * 1000; int down_first = (MF. down % 10) * 1000; int up_last = (MF. up-(MF. up/1000) * 1000)-(MF. up-(MF. up/1000) * 1000)/100) * 100)/10; int down_last = (MF. down-(MF. down/1000) * 1000)-(MF. down-(MF. down/1000) * 1000)/100) * 100)/10; Mf. up = up_f IRST + (MF. up/1000) * 100 + (MF. up-(MF. up/1000) * 1000)/100) * 10 + up_last; Mf. down = down_first + (MF. down/1000) * 100 + (MF. down-(MF. down/1000) * 1000)/100) * 10 + down_last; Result = mf; result. pre = pre; result. OP = 'B'; return 'B';} // operation C 1234 5678-> 1624 5738 char OPC (MF, int pre, MF & result) {int I1 = (MF. up-(MF. up/1000) * 1000)/100; int I2 = (MF. up-(MF. up/1000 )* 1000)-I1 * 100)/10; int J1 = (MF. down-(MF. down/1000) * 1000)/100; int J2 = (MF. down-(MF. down/1000) * 1000)-J1 * 100)/10; Mf. up = (MF. up/1000) * 1000 + J1 * 100 + I1 * 10 + Mf. up % 10; Mf. down = (MF. down/1000) * 1000 + J2 * 100 + I2 * 10 + Mf. down % 10; Result = mf; result. pre = pre; result. OP = 'C'; return 'C';} int main () {int Max; while (CIN> MAX & Max! =-1) {int find_length = 0; int target [8]; int value; memset (isvisited, false, sizeof (isvisited); For (INT I = 0; I <8; I ++) {CIN> value; target [I] = value;} vector <MF> MFs; stack <char> OPS; int fp = 0, rp = 0; bool success = false; int up = target [0] * 1000 + target [1] * 100 + target [2] * 10 + target [3]; // The upstream int down of the target cube = target [7] + target [6] * 10 + target [5] * 100 + target [4] * 1000; // downstream MF of the target cube MF; Mf. up = 1234; Mf. down = 8765; Mf. OP = ''; Mf. pre =-1; MFs. push_back (MF); // if not found, the while (MFs [FP] is searched cyclically. up! = Up | MFs [FP]. Down! = Down) {// or while (MFs [FP]. Up! = Up | MFs [FP]. Down! = Down) // search by breadth first // perform operations on the cube. The first pointer executes the cube that is being operated. The last pointer executes the operation and then enters the cube MF result of the queue; char A = OPA (MFs [FP], FP, result); If (result. up = up & result. down = down) {// if the target cube is found, the Operation Sequence while (result. pre! =-1) {ops. push (result. OP); find_length ++; Result = MFs [result. pre]; // backtracking} success = true; break;} else if (CMP (MFs, result, A, FP) {// If the cube is not in the queue, this cube enters the team RP ++; // tail pointer increments} Char B = OPB (MFs [FP], FP, result); If (result. up = up & result. down = down) {// if the target cube is found, the Operation Sequence while (result. pre! =-1) {ops. push (result. OP); find_length ++; Result = MFs [result. pre]; // backtracking} success = true; break;} else if (CMP (MFs, result, B, FP) {RP ++ ;} char c = OPC (MFs [FP], FP, result); If (result. up = up & result. down = down) {// if the target cube is found, the Operation Sequence while (result. pre! =-1) {ops. push (result. OP); find_length ++; Result = MFs [result. pre]; // backtracking} success = true; break;} else if (CMP (MFs, result, C, FP) {RP ++;} FP ++; // The increment of the header pointer} // if it cannot be found within the specified step, the output is-1 If (find_length> MAX) {cout <-1 <Endl ;} else {cout <find_length <""; while (! Ops. empty () {// locate the cout process in which the output changes from the initial state to the target State <ops. top (); ops. pop () ;}cout <Endl ;}} return 0 ;}
Sicily 1151 simple cube B BFS and hash judgment duplicate Problem Solving