通道:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3466
题意:六边形,多回路全覆盖,有阻碍。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAX_N = 13; 8 const int MAX_M = 13; 9 const int HASH = 1000007; 10 const int MAX_S = 1000007 + 10; 11 12 const int mov[20] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; 13 14 struct node { 15 int head[HASH], nxt[MAX_S], cnt; 16 long long dp[MAX_S], st[MAX_S]; 17 void init() { 18 memset(head, -1, sizeof head); 19 cnt = 0; 20 } 21 void push(long long s, long long v) { 22 int now = s % HASH; 23 for(int i = head[now]; ~i; i = nxt[i]) if(st[i] == s) { 24 dp[i] += v; 25 return ; 26 } 27 st[cnt] = s; dp[cnt] = v; 28 nxt[cnt] = head[now]; 29 head[now] = cnt++; 30 } 31 }d[2]; 32 33 const int n = 8; 34 35 int m; 36 int A[MAX_N][MAX_M]; 37 38 void blank(int i, int j, int cur) { 39 for (int k = 0; k < d[cur].cnt; ++k) { 40 long long v = d[cur].st[k]; 41 if (j == 1) { 42 if (i % 2 == 1) v >>= 1; 43 else v <<= 1; 44 } 45 int a = v >> mov[m + 1] & 1; 46 int b = v >> mov[j] & 1; 47 int c = v >> mov[j] >> 1 & 1; 48 int left = i % 2 == 1 || j != 1; 49 int right = i % 2 == 0 || j != m; 50 int raw = j != m; 51 52 int dd = a + b + c; 53 if (dd == 3) continue; 54 if (dd == 0) { 55 if (left && right) d[cur ^ 1].push(v ^ 3 << mov[j], d[cur].dp[k]); 56 if (left && raw) d[cur ^ 1].push(v ^ 1 << mov[j] ^ 1 << mov[1 + m], d[cur].dp[k]); 57 if (right && raw) d[cur ^ 1].push(v ^ 2 << mov[j] ^ 1 << mov[1 + m], d[cur].dp[k]); 58 } else if (dd == 1) { 59 if (a) v ^= 1 << mov[m + 1]; 60 else if (b) v ^= 1 << mov[j]; 61 else v ^= 2 << mov[j]; 62 if (left) d[cur ^ 1].push(v ^ 1 << mov[j], d[cur].dp[k]); 63 if (right) d[cur ^ 1].push(v ^ 2 << mov[j], d[cur].dp[k]); 64 if (raw) d[cur ^ 1].push(v ^ 1 << mov[m + 1], d[cur].dp[k]); 65 } else { 66 if (a) v ^= 1 << mov[m + 1]; 67 if (b) v ^= 1 << mov[j]; 68 if (c) v ^= 2 << mov[j]; 69 d[cur ^ 1].push(v, d[cur].dp[k]); 70 } 71 } 72 } 73 74 void block(int i, int j, int cur) { 75 for (int k = 0; k < d[cur].cnt; ++k) { 76 long long v = d[cur].st[k]; 77 if (j == 1) { 78 if (i % 2 == 1) v >>= 1; 79 else v <<= 1; 80 } 81 int a = v >> mov[m + 1] & 1; 82 int b = v >> mov[j] & 1; 83 int c = v >> mov[j] >> 1 & 1; 84 if (!a && !b && !c) 85 d[cur ^ 1].push(v, d[cur].dp[k]); 86 } 87 } 88 89 90 int main() { 91 int z = 0; 92 while (2 == scanf("%d%d", &m, &z)) { 93 memset(A, 0, sizeof A); 94 for (int i = 0; i < z; ++i) { 95 char str[3]; 96 scanf("%s", str); 97 A[str[1] - 'A' + 1][str[0] - 'A' + 1] = 1; 98 } 99 int cur = 0; 100 d[cur].init(); 101 d[cur].push(0, 1); 102 for (int i = 1; i <= n; ++i) { 103 for (int j = 1; j <= m; ++j) { 104 d[cur ^ 1].init(); 105 if (A[i][j]) block(i, j, cur); 106 else blank(i, j, cur); 107 cur ^= 1; 108 } 109 //for (int j = 0; j < d[cur].cnt; ++j) 110 // d[cur].st[j] <<= 2; 111 } 112 long long ans = 0; 113 for (int i = 0; i < d[cur].cnt; ++i) if (d[cur].st[i] == 0) 114 ans += d[cur].dp[i]; 115 printf("%lld\n", ans); 116 } 117 return 0; 118 } 119 120 /* 121 122 8 3 123 AE EF FG 124 125 3 5 126 BB CD BF AH CG 127 128 3 8 129 BA BB BC BD BE BF BG BH 130 131 3 6 132 BB BC BD BE BF BG 133 */