Description
Input
Output
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 typedef long long LL; 7 8 const int MAXN = 12; 9 const int SIZEH = 13131; 10 const int MAXH = 20010; 11 12 struct hash_map { 13 int head[SIZEH], size; 14 int state[MAXH], next[MAXH]; 15 LL val[MAXH]; 16 17 void init() { 18 memset(head, -1, sizeof(head)); 19 size = 0; 20 } 21 22 void insert(int st, LL sv) { 23 int h = st % SIZEH; 24 for(int p = head[h]; ~p; p = next[p]) { 25 if(state[p] == st) { 26 val[p] += sv; 27 return ; 28 } 29 } 30 state[size] = st; val[size] = sv; next[size] = head[h]; head[h] = size++; 31 } 32 } hashmap[2]; 33 34 hash_map *cur, *last; 35 int acc[] = {0, -1, 1, 0}; 36 char mat[MAXN][MAXN]; 37 int n, m, en, em; 38 39 int getB(int state, int i) { 40 return (state >> (i << 1)) & 3; 41 } 42 43 void setB(int &state, int i, int val) { 44 state = (state & ~(3 << (i << 1))) | (val << (i << 1)); 45 } 46 47 int getLB(int state, int i) { 48 int ret = i, cnt = 1; 49 while(cnt) { 50 --ret; 51 cnt += acc[getB(state, ret)]; 52 } 53 return ret; 54 } 55 56 int getRB(int state, int i) { 57 int ret = i, cnt = -1; 58 while(cnt) { 59 ++ret; 60 cnt += acc[getB(state, ret)]; 61 } 62 return ret; 63 } 64 65 void update(int x, int y, int state, LL tv) { 66 int left = getB(state, y); 67 int up = getB(state, y + 1); 68 if(mat[x][y] == '#') { 69 if(left == 0 && up == 0) cur->insert(state, tv); 70 return ; 71 } 72 if(left == 0 && up == 0) { 73 if(x == n - 1 || y == m - 1) return ; 74 int newState = state; 75 setB(newState, y, 1); 76 setB(newState, y + 1, 2); 77 cur->insert(newState, tv); 78 } else if(left == 0 || up == 0) { 79 if(x < n - 1) { 80 int newState = state; 81 setB(newState, y, up + left); 82 setB(newState, y + 1, 0); 83 cur->insert(newState, tv); 84 } 85 if(y < m - 1) { 86 int newState = state; 87 setB(newState, y, 0); 88 setB(newState, y + 1, up + left); 89 cur->insert(newState, tv); 90 } 91 } else { 92 int newState = state; 93 setB(newState, y, 0); 94 setB(newState, y + 1, 0); 95 if(left == 1 && up == 1) setB(newState, getRB(state, y + 1), 1); 96 if(left == 1 && up == 2 && !(x == en && y == em)) return ; 97 if(left == 2 && up == 2) setB(newState, getLB(state, y), 2); 98 cur->insert(newState, tv); 99 } 100 } 101 102 void findend() { 103 for(en = n - 1; en >= 0; --en) 104 for(em = m - 1; em >= 0; --em) if(mat[en][em] != '#') return ; 105 } 106 107 LL solve() { 108 findend(); 109 cur = hashmap, last = hashmap + 1; 110 last->init(); 111 last->insert(0, 1); 112 for(int i = 0; i < n; ++i) { 113 int sz = last->size; 114 for(int k = 0; k < sz; ++k) last->state[k] <<= 2; 115 for(int j = 0; j < m; ++j) { 116 cur->init(); 117 sz = last->size; 118 for(int k = 0; k < sz; ++k) 119 update(i, j, last->state[k], last->val[k]); 120 swap(cur, last); 121 } 122 } 123 for(int k = 0; k < last->size; ++k) 124 if(last->state[k] == 0) return last->val[k]; 125 return 0; 126 } 127 128 int main() { 129 while(scanf("%d%d", &n, &m) != EOF) { 130 if(n == 0 && m == 0) break; 131 memset(mat, 0, sizeof(mat)); 132 for(int i = 0; i < n; ++i) scanf("%s", mat[i]); 133 for(int i = 1; i < m - 1; ++i) mat[n][i] = '#'; 134 n += 2; 135 cout<<solve()<<endl; 136 } 137 }