Crazy HorseTime limit (Common/Java): 1000 MS/3000 MS running memory limit: 65536 Kbyte Total submission: 19 pass the test: 5Description There is a dark horse and white horse on a 5x5 board. Each type of horse has 12, so there is exactly a space on the board. At any time, the horse can only move to spaces (as shown in Figure) Given the initial state of the board, snow_storm wants to know how many moves can reach the target State as shown in: Input The first positive integer T (<= 100) indicates the number of test groups. For each group of test data, there are 5 rows in total, each line has 5 characters, indicating the initial state of the Board: '0' indicates the white horse, '1' indicates the black horse, and ''indicates the space. The following is an example of the corresponding status: Output For each group of test data, if the target State cannot be reached within 16 steps (<16), Crazy Horse is output; otherwise, the minimum number of steps is output. For more details, see the sample output.
Sample Input 2 01011 110 1 01110 01010 00100 10110 01 11 10111 01001 00000 Sample output Case 1: Crazy Horse Case 2: 7 Question Source Yb |
Question address:
Http: // 218.194.91.48/acmhome/problemdetail. do? & Method = showdetail & id = 1425
Original question: http://www.lightoj.com question 1143... PS: the original question was changed when the question was output.
========================================================== ========================================================== ==============================
In fact, the code for this question is better implemented as long as you have an idea.
In the initial writing, we used the knowledge of KM matching as a heuristic algorithm to write Ida *.
The KM match only looks at one point. So let the uncle blame (directly set B's template )...
You can create a matching image by yourself. At the beginning, you can create a new BFS image for each matching...
Result: The test data of TLE is in the first group... Therefore, the number of steps from all locations to any location is preprocessed, and the matching graph creation time is only O (5*5*12 )...
Again, TLE tests data in the second group...
At the beginning, I thought about pruning. When you move forward, remember the direction at this time. When you are in the next position, make a judgment and leave the opposite direction...
But it is still in the second group. It seems that the pruning is ineffective...
You can only record the status and identify the duplicate status... I don't know how B's brother records the status (seems to be related to backward stars ?)
After thinking about it, I suddenly thought of using the dictionary tree... ... The time is enough. In this example, we can't go through it. We can go in Step 13 and take 15 steps...
Then I thought about it and found a bug: DFS is a deep search, that is, the status generated in step 1 in this direction. Maybe it only takes three steps in the other direction...
Therefore, the status judgment cannot only determine whether or not it has been passed, but also determines that a few steps can be taken again...
# Include <iostream> # include <cstdio> # include <cstring> # include <algorithm> using namespace STD; char P [6] [6]; // match the current map at DFS ================================ ===== const int maxn = 33; const int INF = 0x3fffffff; int Tol, n, m, mat [maxn], LX [maxn], Ly [maxn], lack, map [maxn] [maxn]; bool visx [maxn], visy [maxn]; bool find (int x) {int I, V, Y; visx [x] = true; for (I = 1; I <= N; I ++) {Y = I; If (! Visy [y]) {int T = Lx [x] + ly [y]-map [x] [Y]; If (! T) {visy [y] = true; If (MAT [y] =-1 | find (MAT [y]) {mat [y] = X; return true ;}} else if (lack> T) lack = T ;}} return false ;}int km () {int I, j, X, Y; /* // output the current map, cout with the diagram result <"P ------" <Endl; for (I = 0; I <5; I ++) {puts (P [I]) ;}cout <"map ------" <Endl; for (I = 1; I <= N; I ++) {for (j = 1; j <= m; j ++) cout <map [I] [J] <""; cout <Endl ;} */memset (MAT,-1, sizeof (MAT); for (I = 1; I <= N; I ++) {lx [I] =-INF; ly [I] = 0; For (j = 1; j <= N; j ++) {x = map [I] [J ]; If (x> lx [I]) lx [I] = x ;}}for (I = 1; I <= N; I ++) {While (1) {memset (visx, false, sizeof (visx); memset (visy, false, sizeof (visy); lack = inf; If (find (I) break; for (j = 1; j <= N; j ++) {If (visx [J]) lx [J]-= lack; If (visy [J]) ly [J] + = lack ;}}int ret = 0; for (I = 1; I <= N; I ++) {If (MAT [I]! =-1) RET + = Lx [Mat [I], RET + = ly [I];} return ret;} // diagram (for KM matching) ============ int FX [] = {-,-, 1,-,-1 }; int FY [] = {-, 1,-,-2,-}; int D1 [5] [5] = {, 5 }, {, 9}, {0, 11}, {0, 0, 12}, {0, 0, 0 }}; int D2 [5] [5] = {0, 0, 0, 0}, {12, 0, 0, 0}, {10, 11, 0, 0, 0}, {6, 7, 8, 9, 0 },{ 1, 2, 4, 5 }}; int rec [6] [6] [6] [6]; struct node {int X, Y; node () {} node (int A, int B) {x = A, y = B;} que [20000]; void deal () {// preprocessing arbitrary coordinates Shortest steps between (x1, Y1) and any coordinate (X2, Y2) int I, j, vis [6] [6], SS, St, CNT = 1, NX, NY, K, TX, Ty; for (I = 0; I <5; I ++) for (j = 0; j <5; j ++) {memset (VIS,-1, sizeof (VIS); que [Ss = sT = 0] = node (I, j); vis [I] [J] = 0; while (SS <= sT) {Nx = que [ss]. x; ny = que [ss]. y; SS ++; If (d1 [NX] [NY]! = 0) Rec [I] [J] [NX] [NY] =-vis [NX] [NY]; If (D2 [NX] [NY]! = 0) Rec [I] [J] [NX] [NY] =-vis [NX] [NY]; for (k = 0; k <8; k ++) {Tx = NX + FX [k]; ty = ny + FY [k]; If (TX <0 | ty <0 | TX> 4 | ty> 4) continue; If (vis [TX] [ty]! =-1) continue; vis [TX] [ty] = vis [NX] [NY] + 1; ST ++; que [st]. X = TX; que [st]. y = ty ;}} CNT ++ }}int bfs1 () {// match the black horse int I, j, G, F, CNT = 1; for (I = 0; I <5; I ++) for (j = 0; j <5; j ++) if (P [I] [J] = '1 ') {for (G = 0; G <5; G ++) for (F = (G <2? G: G + 1); F <5; F ++) map [CNT] [D1 [g] [f] = rec [I] [J] [g] [f]; CNT ++;} n = 12, M = 12; return km () ;}int bfs2 () {// match White Horse int I, j, G, F, CNT = 1; for (I = 0; I <5; I ++) for (j = 0; j <5; j ++) if (P [I] [J] = '0 ') {for (G = 0; G <5; G ++) for (F = (G> 2? G: g-1); F> = 0; f --) map [CNT] [D2 [g] [f] = rec [I] [J] [g] [f]; CNT ++;} n = 12, M = 12; return km () ;}// dictionary tree (for storage status) ====================== struct tree {int step; tree * Next [3] ;}; tree * root; void init _ (TREE * X) {// initialize the new node X-> step = 10000; x-> next [0] = x-> next [1] = x-> next [2] = 0;} int cover (INT step) {// Add the dictionary tree * New _, * Now = root; int I, J, K, flag = 0; for (I = 0; I <5; I ++) for (j = 0; j <5; j ++) {If (P [I] [J] = '0') k = 0; else if (P [I] [J] = '1') k = 1; else K = 2; If (now-> next [k] = 0) {New _ = new tree; init _ (New _); now-> next [k] = new _;} Now = now-> next [k];} if (now-> Step> step) {// determine if you can go now-> step = step; flag = 1;} return flag;} void CLR (TREE * X) {// Delete the dictionary tree (releasing memory) if (X-> next [0]) CLR (X-> next [0]); if (X-> next [1]) CLR (X-> next [1]); If (X-> next [2]) CLR (X-> next [2]); Delete x ;}// heuristic search ================ bool DFS (int x, int y, int step, int TOL) {int K, H, NX, NY; H =-(bfs1 () + bfs2 ()); // heuristic if (H = 0) return true; If (H + Step> TOL) return false; For (k = 0; k <8; k ++) {Nx = x + FX [k]; ny = Y + FY [k]; If (nx <0 | ny <0 | NX> 4 | ny> 4) continue; swap (P [NX] [NY], p [x] [Y]); If (cover (Step + 1 )) // check whether the status has passed if (DFS (NX, NY, step + 1, Tol) return true; swap (P [NX] [NY], P [x] [Y]);} return false;} // main function ================== int main () {int TT, T, Si, SJ, I, j; bool res; char MP [6] [6]; Deal (); scanf ("% d ", & T); getchar (); For (TT = 1; TT <= T; TT ++) {for (I = 0; I <5; I ++) {gets (MP [I]); memcpy (P [I], MP [I], 5); For (j = 0; j <5; j ++) if (MP [I] [J] = '') SI = I, SJ = J;} I = bfs1 () + bfs2 (); if (I <16) for (I = 0; I <16; I ++) {// Dia * For (j = 0; j <5; j ++) memcpy (P [J], MP [J], 5); root = new tree; // create dictionary tree init _ (Root); cover (0); Res = DFS (Si, SJ, 0, i); CLR (Root); If (RES) break;} printf ("case % d:", TT); if (I <16) printf ("% d \ n", I); else puts ("Crazy Horse");} return 0;}/* 100111011111111100 0000000 */