Test instructions: give you a M * n chessboard, some of which are obstacles, and ask how many loops make it happen once every non-barrier lattice. M, n≤12.
As shown in figure, M = n = 4, (1, 1), (1, 2) is a barrier, and there are 2 circuits that meet the requirements.
This problem begins to look at the Chen Danqi of the paper, see is understood but will not be realized, and later saw a better approach, the plug connectivity is expressed in parentheses, so that each state there are only three kinds, specifically see
Http://blog.sina.com.cn/s/blog_51cea4040100gmky.html
PS: Always do five points however, there will be a class, quickly moved by their own tears ...
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <iostream > #include <algorithm> #include <vector> #include <map> #include <queue> #include <stack > #include <string> #include <map> #include <set> #include <ctime> #define EPS 1e-6 #define LL
Long Long #define PII pair<int, int>//#pragma comment (linker, "/stack:1024000000,1024000000") using namespace std;
const int MAXN = 100 + 5;
const int INF = 0X3F3F3F3F;
const int hashsize = 2000000;//Total State has 3^13, size makes a big benefit to reduce the conflict, but increases the time to empty the memory.
int hash[hashsize];
int n, m, index, ex, EY;
int total[2], state[2][hashsize], bit[100];
LL Dp[2][hashsize], ans;
int map[15][15];
void Init () {memset (map, 0, sizeof map);
index = 0;
Total[0] = 1;
STATE[0][1] = 0;
DP[INDEX][1] = 1;
Ans = 0;
} void hashcal (int s, LL num) {int hashpos = s% hashsize; while (Hash[hashpos]! =-1) {if (State[index][hash[hashpos]] = = s) {Dp[index][hash[hashPos]] + = num;
Return
} hashpos++;
if (hashpos==hashsize) hashpos = 0;
} total[index]++;
DP[INDEX][TOTAL[INDEX]] = num;
Hash[hashpos] = Total[index];
State[index][total[index]] = s;
} void DP () {for (int i = 1, i <= N; i++) {for (int k = 1; k <= Total[index]; k++) state[index][k] <<= 2;
for (int j = 1; j <= M; j + +) {index ^= 1;
Total[index] = 0;
memset (hash,-1, sizeof hash);
for (int k = 1; k <= total[index^1]; k++) {int s = state[index^1][k];
LL num = dp[index^1][k];
int p = (s>>bit[j-1])% 4;
int q = (s>>bit[j])% 4;
if (num==0) cout << i << "<< J <<" "<< s << endl; if (!
Map[i][j]) {if (p+q = = 0) hashcal (s, num); } else if (p+q = = 0) {if (! MAP[I+1][J] | | !
MAP[I][J+1]) continue;
s + = (1<<bit[j-1]) + (1<< (bit[j]+1));
Hashcal (S, num);
} else if (!p && q) {if (map[i][j+1]) hashcal (S, num); if (map[i+1][j]) {s + = (1<<bit[j-1]) *q-(1<<bit[j]) *q;
Hashcal (S, num);
}} else if (!q && p) {if (Map[i+1][j]) hashcal (S, num);
if (Map[i][j+1]) {s + = (1<<bit[j]) *p-(1<<bit[j-1]) *p;
Hashcal (S, num); }} else if (p+q = = 2) {//merge connected block int b = 1;//Find Nearest right parenthesis for (int t = j+1; t <= m; t++) {int v =
(S>>bit[t])% 4;
if (v = = 1) b++;
if (v = = 2) b--;
if (!b) {s-= (1<<bit[t]);
Break
}} s = S-(1<<bit[j-1])-(1<<bit[j]);
Hashcal (S, num);
} else if (p+q = = 4) {int b=1;
for (int t = j-2; t >= 0; t--) {//find nearest match bracket int v = (s>>bit[t])% 4;
if (v = = 2) ++b;
if (v = = 1)--b;
if (!b) {s + = (1<<bit[t]);//Turn the opening parenthesis into a closing parenthesis Break
}} s = s-2* (1<<bit[j-1])-(1<<bit[j]);
Hashcal (S, num);
} else if (p==2 && q==1) {s = S-(1<< (bit[j-1]+1))-(1<< (bit[j]));
Hashcal (S, num);
} else if (p==1 && q==2) {//cout << i << J << Endl;
if (I==ex && j==ey) ans + = num;
cout << ans << endl;
}}}}} int main () {//freopen ("Input.txt", "R", stdin); for (int i = 0; I <=; i++) bit[i] = i<<1;
For the first plug I need to move to the right position while (scanf ("%d%d", &n, &m) ==2) {init ();
Char op;
for (int i = 1; I <= n; i++) {GetChar ();
for (int j = 1; j <= M; j + +) {scanf ("%c", &op); if (op== '. ')
MAP[I][J] = 1, ex = i, ey = j;
}}//cout << ex << ey << Endl;
DP ();
printf ("%i64d\n", ans);
} return 0;
}