和画圈圈有点像,用射线法区分是在回路里面内部还是回路外部,回路内部不允许产生回路
#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::stringstream; using std::make_pair; using std::getline; using std::greater; using std::endl; using std::multimap; using std::deque; using std::unique; using std::lower_bound; using std::random_shuffle; typedef long long LL; typedef unsigned long long ULL; typedef pair<int, int> PAIR; typedef multimap<int, int> MMAP; typedef LL TY; const int MAXN(600010); const int MAXM(5010); const int MAXE(10010); const int MAXK(6); const int HSIZE(131313); const int SIGMA_SIZE(26); const int MAXH(19); const int INFI((INT_MAX-1) >> 1); const ULL BASE(31); const LL LIM(10000000); const int INV(-10000); const int MOD(1000000007); const double EPS(1e-8); template<typename T> void checkmax(T &a, T b){if(b > a) a = b;} template<typename T> void checkmin(T &a, T b){if(b < a) a = b;} template<typename T> T ABS(const T &a){return a < 0? -a: a;} int MS; struct HASH_MAP { int first[HSIZE], next[MAXN]; int value[MAXN]; LL state[MAXN]; int size; void init() { memset(first, -1, sizeof(first)); size = 0; } void insert(LL ts, int tv) { int h = ts%HSIZE; for(int i = first[h]; ~i; i = next[i]) if(state[i] == ts) { value[i] += tv; if(value[i] >= MOD) value[i] -= MOD; return; } value[size] = tv; state[size] = ts; next[size] = first[h]; first[h] = size++; } } hm[2]; HASH_MAP *cur, *last; char mp[15][15]; int N, M, K; int acc[4] = {0, -1, 1, 0}; int mul3[15]; int getB(LL ts, int i) { return (ts >> mul3[i])&3; } int getLB(LL ts, int i) { int ret = i, cnt = 1; while(cnt) { --ret; cnt += acc[getB(ts, ret)]; } return ret; } int getRB(LL ts, int i) { int ret = i, cnt = -1; while(cnt) { ++ret; cnt += acc[getB(ts, ret)]; } return ret; } void setB(LL &ts, int i, LL tv) { ts = (ts&~(3LL << mul3[i]))|(tv << mul3[i]); } int getP(LL ts, int i) { return (ts >> mul3[i])&4; } void setP(LL &ts, int i, LL tv) { ts = (ts&~(4LL << mul3[i]))|(tv << mul3[i]); } int getQ(LL ts) { return ts >> mul3[M+1]; } void setQ(LL &ts, LL tv) { ts = (ts&((1LL << mul3[M+1])-1))|(tv << mul3[M+1]); } void updata(int x, int y, LL ts, int tv) { int lb = (y == 0)? 0: getB(ts, y); int ub = (x == 0)? 0: getB(ts, y+1); int up = (y == 0)? 0: getP(ts, y+1); int q = getQ(ts); LL tts; if(mp[x][y] == '*') { if(lb == 0 && ub == 0) { tts = ts; setB(tts, y, 0); setB(tts, y+1, 0); setP(tts, y, up); cur->insert(tts, tv); } return; } if(lb == 0 && ub == 0) { if(x == N-1 || y == M-1) return; tts = ts; setB(tts, y, 1); setB(tts, y+1, 2); setP(tts, y, up^4); cur->insert(tts, tv); } else if(lb == 0 || ub == 0) { if(x < N-1) { tts = ts; setB(tts, y, lb+ub); setB(tts, y+1, 0); setP(tts, y, up); cur->insert(tts, tv); } if(y < M-1) { tts = ts; setB(tts, y, 0); setB(tts, y+1, lb+ub); setP(tts, y, up^4); cur->insert(tts, tv); } } else { if(lb == 1 && ub == 1) { tts = ts; setB(tts, getRB(ts, y+1), 1); setB(tts, y, 0); setB(tts, y+1, 0); setP(tts, y, up); cur->insert(tts, tv); } if(lb == 1 && ub == 2) { if(q == K || up != 0) return; tts = ts; setB(tts, y, 0); setB(tts, y+1, 0); setP(tts, y, up); setQ(tts, q+1); cur->insert(tts, tv); } if(lb == 2 && ub == 1) { tts = ts; setB(tts, y, 0); setB(tts, y+1, 0); setP(tts, y, up); cur->insert(tts, tv); } if(lb == 2 && ub == 2) { tts = ts; setB(tts, getLB(ts, y), 2); setB(tts, y, 0); setB(tts, y+1, 0); setP(tts, y, up); cur->insert(tts, tv); } } } void solve() { cur = hm; last = hm+1; last->init(); last->insert(0, 1); for(int i = 0; i < N; ++i) { int sz = last->size; for(int j = 0; j < sz; ++j) last->state[j] = (last->state[j]&~((1LL << mul3[M+1])-1))|((last->state[j]&((1LL << mul3[M])-1)) << 3); for(int j = 0; j < M; ++j) { cur->init(); sz = last->size; for(int k = 0; k < sz; ++k) updata(i, j, last->state[k], last->value[k]); swap(cur, last); } } int ans = 0; for(int i = 0; i < last->size; ++i) { bool flag = getQ(last->state[i]) == K; for(int j = 0; flag && j <= M; ++j) if(getB(last->state[i], j)) flag = false; if(flag) { ans += last->value[i]; if(ans >= MOD) ans -= MOD; } } printf("%d\n", ans); } int main() { for(int i = 0; i <= 13; ++i) mul3[i] = i*3; int TC; scanf("%d", &TC); while(TC--) { scanf("%d%d%d", &N, &M, &K); int cnt = 0; for(int i = 0; i < N; ++i) { scanf("%s", mp[i]); for(int j = 0; j < M; ++j) if(mp[i][j] == '.') ++cnt; } if(K > cnt/4) { printf("0\n"); continue; } solve(); } }