Tony's tour
Time limit:1000 ms |
|
Memory limit:30000 K |
Total submissions:2920 |
|
Accepted:1343 |
Description A square township has been divided up into N * m (N rows and M columns) square plots (1 <= n, m <= 8), some of them are blocked, others are unblocked. the farm is located in the lower left plot and the market is located in the lower right plot. tony takes her tour The township going from farm to market by walking through every unblocked plot exactly once. Write a program that will count how many unique tours Betsy can take in going from farm to market.Input The input contains several test cases. the first line of each test case contain two integer numbers n, m, denoting the number of rows and columns of the farm. the following n lines each contains M characters, describe the farm. a' # 'means a blocked square, A'. 'means a unblocked square. The last test case is followed by two zeros.Output For each test case output the answer on a single line.Sample Input 2 2....2 3#.....3 4............0 0 Sample output 114 Source Loutiancheng @ poj |
This is similar to Ural 1519 Formula 1. Just change the loop to the lower left corner as the starting point. The number of loops in the lower right corner to the end. Therefore, add two rows for preprocessing.
For example:
3 4 ....
........
... ----------> ....
.....##.
....
In this way, after preprocessing, the question will be the same.
# Include <stdio. h> # include <string. h> # include <iostream> # include <algorithm> using namespace STD; const int hash = 30007; // the size of the hash table const int state = 1000010; // number of States const int maxd = 15; int n, m, ex, ey; // ex, ey last int code [maxd], maze [maxd] [maxd], mcod [maxd]; // encoding. And save the map. Minimum representation char s [20]; struct hashmap // Hash Table Structure {int head [hash], next [State], SZ; // use a linked list to connect the hash table with the same module. It is convenient to search for and Judge long f [State], State [State]; // number of methods in the corresponding state of F records. Next points to the next state with the same modulus. State record status. Total number of SZ record statuses void Init () // hash table initialization function {SZ = 0; memset (Head,-1, sizeof (head);} void push (long St, long long ans) // The Press status and number of methods {int I, H = sT % hash; for (I = head [H]; I! =-1; I = next [I]) if (ST = State [I]) // If the status already exists. If the number of methods is increased, {f [I] + = ans; return;} f [SZ] = ans; // Save the new feasible state State [SZ] = sT; next [SZ] = head [H]; head [H] = SZ ++;} hm [2]; void decode (int * code, int M, long St) // encoding starts from the high position to the low position m to the 0 encoding. Corresponding plug {int I; for (I = m; I> = 0; I --) {code [I] = sT & 7; st >>>= 3 ;}} long encode (int * code, int m) // The minimum representation is decoded to {int I, CNT = 1; long long St = 0; memset (mcod,-1, sizeof mcod); mcod [0] = 0; for (I = 0; I <= m; I ++) {If (mcod [Code [I] =-1) mcod [Code [I] = CNT ++; Code [I] = mcod [Code [I]; st <= 3; ST | = Code [I];} return st;} void Init () // read data. Initialize {int I, j; memset (maze, 0, sizeof maze); Ex = 0; for (I = 1; I <= N; I ++) {scanf ("% s", S + 1); For (j = 1; j <= m; j ++) if (s [J] = '. ') maze [I] [J] = 1;} maze [n + 1] [1] = maze [n + 1] [m] = 1; for (I = 2; I <m; I ++) maze [n + 1] [I] = 0; for (I = 1; I <= m; I ++) maze [n + 2] [I] = 1; n + = 2; Ex = N, ey = m;} void shift (int * code, int m) // shift when wrapping {int I; for (I = m; I> 0; I --) Code [I] = Code [I-1]; code [0] = 0;} void dpblank (int I, Int J, int cur) // handle the case where the cells are reachable {int K, T, lef T, up, temp; For (k = 0; k <HM [cur]. SZ; k ++) // traverses the status of the J-cell output contour line for state transfer {decode (Code, M, HM [cur]. state [k]); // encode the State left = Code [J-1]; // obtain the left plug status up = Code [J]; // obtain the status of the upper plug if (left & UP) // 11-> 00 {If (Left = up) // forming the loop {if (I = ex & J = ey) // determine whether it reaches the last point {code [J-1] = Code [J] = 0; // It can only be 0 and one grid can only have two plug if (j = m) shift (Code, m); // line feed HM [cur ^ 1] after reaching the boundary. push (encode (Code, m), HM [cur]. f [k]); // press new status} else {code [J-1] = Code [J] = 0; For (t = 0; t <= m; t ++) If (code [T] = up) {code [T] = left; break;} If (j = m) shift (Code, M ); // line feed HM [cur ^ 1] After the boundary is reached. push (encode (Code, m), HM [cur]. f [k]); // press in new status} else if ((! Left & UP) | (left &&! Up) // 01 or 10 {If (up) temp = up; else temp = left; If (maze [I] [J + 1]) // when J = m, maze [I] [J] is 0 and shift {code [J-1] = 0; Code [J] = temp; HM [cur ^ 1]. push (encode (Code, m), HM [cur]. f [k]);} If (maze [I + 1] [J]) {code [J-1] = temp; Code [J] = 0; if (j = m) shift (Code, m); // do not forget this! HM [cur ^ 1]. push (encode (Code, m), HM [cur]. f [k]) ;}} else {If (maze [I] [J + 1] & maze [I + 1] [J]) // shift {code [J] = Code [J-1] = 13; HM [cur ^ 1] is not required if J = m is not legal. push (encode (Code, m), HM [cur]. f [k]) ;}}} void dpblock (int I, Int J, int cur) // handle the case where the cell cannot be reached {int K; For (k = 0; k <HM [cur]. SZ; k ++) // The storage status is valid. You do not need to judge {decode (Code, M, HM [cur]. state [k]); // encode code first [J-1] = Code [J] = 0; // certainly cannot use plug if (j = m) shift (code, m); // move to the next row HM [cur ^ 1]. push (encode (Code, m), HM [cur]. f [k]) ;}} void solve () {int I, j, cur = 0; long ans = 0; HM [cur]. init (); // cur is used to scroll the array. Save space. Cur stores the current plug and left plug. Cur ^ 1 is used to record the new State transferred out, that is, the next cell HM [cur]. push (0, 1); for (I = 1; I <= N; I ++) for (j = 1; j <= m; j ++) {HM [cur ^ 1]. init (); // initialize if (maze [I] [J]) dpblank (I, j, cur); else dpblock (I, j, cur ); cur ^ = 1 ;}for (I = 0; I <HM [cur]. SZ; I ++) ans + = HM [cur]. f [I]; printf ("% i64d \ n", ANS);} int main () {While (scanf ("% d", & N, & M), N | M) {Init (); If (! Ex) printf ("0 \ n"); else solve ();} return 0 ;}