确定了起点和终点的简单路径问题,和简单回路差不多,注意处理起点和终点以及特殊情况即可。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::istringstream; using std::make_pair; using std::getline; using std::greater; using std::endl; using std::multimap; using std::deque; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PAIR; typedef multimap<int, int> MMAP; const int MAXN(1000010); const int MAXM(10010); const int MAXE(10010); const int HSIZE(13131); const int SIGMA_SIZE(26); const int MAXH(19); const int INFI(2000000000); const int MOD(100000000); const ULL BASE(31); const LL LIM(10000000); const int INV(-10000); struct HASH_MAP { int first[HSIZE], next[MAXN]; int state[MAXN]; LL value[MAXN]; int size; void init() { memset(first, -1, sizeof(first)); size = 0; } void insert(int ts, LL tv) { int h = ts%HSIZE; for(int i = first[h]; ~i; i = next[i]) if(state[i] == ts) { value[i] += tv; return; } state[size] = ts; value[size] = tv; next[size] = first[h]; first[h] = size++; } }hm[2]; HASH_MAP *cur, *last; char mp[10][10]; int code[10], Num[8]; void decode(int m, int ts) { for(int i = 0; i <= m; ++i) { code[i] = ts&7; ts >>= 3; } } int encode(int m) { int ret = 0, cnt = 0; memset(Num, -1, sizeof(Num)); for(int i = m; i >= 0; --i) if(code[i] == 0) ret <<= 3; else { if(Num[code[i]] < 0) Num[code[i]] = ++cnt; ret = (ret << 3)|Num[code[i]]; } return ret; } int si, sj, ei, ej; inline bool startgrid(int i, int j){ return i == si && j == sj;} inline bool endgrid(int i, int j){ return i == ei && j == ej;} void updata(int i, int j, int m, LL tv) { int up = (i == 0)? 0: code[j+1]; int left = (j == 0)? 0: code[j]; if(mp[i][j] == '#') { if(up == 0 && left == 0) { code[j] = code[j+1] = 0; cur->insert(encode(m), tv); } return; } if(up == 0 && left == 0) { if(j == m-1) return; if(startgrid(i, j)) { code[j] = 0; code[j+1] = 7; cur->insert(encode(m), tv); return; } code[j] = code[j+1] = 7; cur->insert(encode(m), tv); } else if(up == 0 || left == 0) { if(startgrid(i, j) || endgrid(i, j)) { code[j] = code[j+1] = 0; cur->insert(encode(m), tv); return; } code[j] = left+up; code[j+1] = 0; cur->insert(encode(m), tv); if(j == m-1) return; code[j] = 0; code[j+1] = left+up; cur->insert(encode(m), tv); } else if(up != left) { if(endgrid(i, j)) return; for(int k = 0; k <= m; ++k) if(code[k] == up) code[k] = left; code[j] = code[j+1] = 0; cur->insert(encode(m), tv); } } void solve(int n, int m) { cur = hm; last = hm+1; last->init(); last->insert(0, 1); for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) { cur->init(); int sz = last->size; for(int k = 0; k < sz; ++k) { decode(m, last->state[k]); if(j == 0) for(int k2 = m; k2 >= 1; --k2) code[k2] = code[k2-1]; updata(i, j, m, last->value[k]); } swap(cur, last); } LL ans = 0; for(int i = 0; i < last->size; ++i) if(last->state[i] == 0) { ans = last->value[i]; break; } printf("%I64d\n", ans); } int main() { int n, m; while(scanf("%d%d", &n, &m), n || m) { for(int i = 0; i < n; ++i) scanf("%s", mp[i]); si = n-1; sj = 0; ei = n-1; ej = m-1; if(mp[si][sj] == '#' || mp[ei][ej] == '#') { printf("0\n"); continue; } if(n == 1 && m == 1) { printf("1\n"); continue; } solve(n, m); } return 0; }