去年的老朋友。挺怀念的,回来看看。
$n leq 12,m leq 12$,$n*m$的01矩形,问在0中走路的欧拉回路数。答案保证longlong范围。
先设计插头:左右括号和空插头;然后分3*3种情况转移。耐心。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 //#include<time.h> 5 //#include<complex> 6 #include<algorithm> 7 #include<stdlib.h> 8 using namespace std; 9 10 int n,m; bool mp[14][14]; 11 #define maxn 2333333 12 #define LL long long 13 int state[2][maxn],len[2]; LL ans[2][maxn]; int cur; 14 int Next[maxn],first[maxn]; 15 16 void insert(int x,LL v) 17 { 18 int y=cur^1,h=x%maxn; 19 for (int i=first[h];i;i=Next[i]) if (state[y][i]==x) {ans[y][i]+=v; return;} 20 state[y][++len[y]]=x; ans[y][len[y]]=v; 21 Next[len[y]]=first[h]; first[h]=len[y]; 22 } 23 24 int main() 25 { 26 scanf("%d%d",&n,&m); 27 for (int i=1;i<=n;i++) 28 for (int j=1;j<=m;j++) 29 { 30 char c; while ((c=getchar())!='.' && c!='*'); 31 mp[i][j]=(c=='*'); 32 } 33 //0 kong di 1 zhang ai 34 35 int endx=0,endy; 36 for (int i=n;i && !endx;i--) 37 for (int j=m;j;j--) 38 if (!mp[i][j]) {endx=i; endy=j; break;} 39 40 cur=1; insert(0,1); cur=0; LL Ans=0; 41 for (int i=1;i<=n;i++) 42 for (int j=1;j<=m;j++) 43 { 44 for (int k=1;k<=len[cur];k++) first[state[cur][k]%maxn]=0; 45 for (int k=1;k<=len[cur];k++) 46 { 47 int now=state[cur][k],p=now&3,q=(now>>2)&3,nk; 48 if (mp[i][j]) {if (p==0 && q==0) nk=now>>2,insert(nk,ans[cur][k]);} 49 else if (p==0 && q==0) {if (j<m) {nk=(now>>2)|2|(1<<(m<<1)); insert(nk,ans[cur][k]);}} 50 else if (p==0 && q) 51 { 52 nk=((now>>2)^q)|(q<<(m<<1)); insert(nk,ans[cur][k]); 53 if (j<m) {nk=now>>2; insert(nk,ans[cur][k]);} 54 } 55 else if (p && q==0) 56 { 57 nk=(now>>2)|(p<<(m<<1)); insert(nk,ans[cur][k]); 58 if (j<m) {nk=(now>>2)|p; insert(nk,ans[cur][k]);} 59 } 60 else if (p==1 && q==1) 61 { 62 int cnt=1; nk=(now>>2)^q; 63 for (int l=2;;l++) 64 { 65 int hh=(now>>(l<<1))&3; 66 if (hh==1) cnt++; if (hh==2) cnt--; 67 if (cnt==0) {nk=(nk^(2<<((l-1)<<1)))^(1<<((l-1)<<1)); break;} 68 } 69 insert(nk,ans[cur][k]); 70 } 71 else if (p==2 && q==1) 72 { 73 nk=(now>>2)^q; 74 insert(nk,ans[cur][k]); 75 } 76 else if (p==1 && q==2) {if (i==endx && j==endy && (now^p^(q<<2))==0) Ans+=ans[cur][k];} 77 else if (p==2 && q==2) 78 { 79 int cnt=1,nk=(now>>2)^q; 80 for (int l=m;;l--) 81 { 82 int hh=(now>>(l<<1))&3; 83 if (hh==2) cnt++; if (hh==1) cnt--; 84 if (cnt==0) {nk=(nk^(1<<((l-1)<<1)))^(2<<((l-1)<<1)); break;} 85 } 86 insert(nk,ans[cur][k]); 87 } 88 } 89 len[cur]=0; 90 cur^=1; 91 } 92 printf("%lld ",Ans); 93 return 0; 94 }