Separate the Animals

There are some animals in a zoo which can be described as a grid with N rows and M columns. Your task is to place some obstacles so that no pairs of animals can reach each other.

Two animals can reach each other if and only if their cells are 4-connected. For example, in Figure 1, the central blue cell can be reached by the four red cells, and cannot be reached by the other four white cells.

sep1.JPG

Figure 1

What is more, you must put obstacles in exactly K cells, which are 4-connected and form exactly H holes. Here a hole is defined as a 4-connected part with finitely many open cells while the zoo is placed in an infinite open grid. For example, there are 2 holes (the green and the yellow areas) in Figure 2.

sep2.JPG

Figure 2

For the following grid with two animals:

sep3.jpg

Figure 3

If K = 8 and H = 1, one way to separate them is the following:

sep4.jpg

Figure 4

Figure 5 is illegal because it contains no hole.

sep5.jpg

Figure 5

Figure 6 is also illegal because the obstacles are not 4-connected.

sep6.jpg

Figure 6

Given some animals, you are supposed to count the number of different solutions.

Input Specification:

Each input file contains one test case. For each case, the first line gives four integers: N, M, K, H (2 ≤ N, M ≤ 6; 1 ≤ K ≤ 12; 0 ≤ H ≤ 2). All the numbers are separated by spaces.

Then N lines follow, each contains M characters, which are either . or O, representing an open cell or an animal, respectively. There will be at least 2 animals.

Output Specification:

For each case, print a single line containing a single integer: the number of solutions.

Sample Input:

3 5 8 1
...O.
.O...
.....
 

Sample Output:

8
  1 #include<map> 
  2 #include<set>
  3 #include<ctime>  
  4 #include<cmath>      
  5 #include<queue>   
  6 #include<string>  
  7 #include<vector>  
  8 #include<cstdio>      
  9 #include<cstring>    
 10 #include<iostream>  
 11 #include<algorithm>      
 12 #include<functional>  
 13 using namespace std;
 14 #define ms(x,y) memset(x,y,sizeof(x))      
 15 #define rep(i,j,k) for(int i=j;i<=k;i++)      
 16 #define per(i,j,k) for(int i=j;i>=k;i--)      
 17 #define loop(i,j,k) for (int i=j;i!=-1;i=k[i])      
 18 #define inone(x) scanf("%d",&x)      
 19 #define intwo(x,y) scanf("%d%d",&x,&y)      
 20 #define inthr(x,y,z) scanf("%d%d%d",&x,&y,&z)    
 21 #define infou(x,y,z,p) scanf("%d%d%d%d",&x,&y,&z,&p)   
 22 #define lson x<<1,l,mid  
 23 #define rson x<<1|1,mid+1,r  
 24 #define mp(i,j) make_pair(i,j)  
 25 #define ff first  
 26 #define ss second  
 27 typedef int LL;
 28 typedef pair<LL, LL> pii;
 29 const int low(int x) { return x&-x; }
 30 const double eps = 1e-6;
 31 const int INF = 0x7FFFFFFF;
 32 const int mod = 1e9 + 7;
 33 const int N = 15;
 34 int n, m, t, h;
 35 int fa[N*N][N*N], ga[N*N][N*N], sa[N*N][N*N], a[N][N], ans, vis[N][N];
 36 int ha[N*N][N*N], hole[N], b[N*N];
 37 char s[N][N];
 38 int dir[4][2] = { 0,1,0,-1,1,0,-1,0 };
 39  
 40 int get(int fa[], int x) {
 41   return fa[x] == x ? x : fa[x] = get(fa, fa[x]);
 42 }
 43  
 44 void dfs(int now, int cnt, int con) {
 45   if (cnt > t) return;
 46   if (con - 1 > t - cnt) return;
 47   if (t - cnt > n*m - now + 1) return;
 48   if (now > n * m) {
 49     if (cnt < t || con != 1 || hole[now - 1] != h) return;
 50     ans++; 
 51     return;
 52   }
 53  
 54   int x = (now - 1) / m + 1, y = (now - 1) % m + 1;
 55   rep(i, 1, n*m) {
 56     fa[now][i] = fa[now - 1][i];
 57     ga[now][i] = ga[now - 1][i];
 58     sa[now][i] = sa[now - 1][i];
 59     ha[now][i] = ha[now - 1][i];
 60   }
 61   hole[now] = hole[now - 1] + 1;
 62   if (con == 1 && cnt == t) {
 63  
 64   }
 65   else if (now > m) {
 66     int sz = 0;
 67     rep(i, 1, m) {
 68       int x = (now - i - 1) / m + 1, y = (now - i - 1) % m + 1;
 69       if (!a[x][y]) continue;
 70       b[sz++] = get(fa[now], now - i);
 71     }
 72     sort(b, b + sz);
 73     sz = unique(b, b + sz) - b;
 74     if (sz < con) {
 75       return;
 76     }
 77   }
 78  
 79   if (y > 1 && !a[x][y - 1]) {
 80     int fx = get(ha[now], now), fy = get(ha[now], now - 1);
 81     if (fx != fy) {
 82       if (!fx || !fy) ha[now][fx + fy] = 0;
 83       else  ha[now][fx] = fy;
 84       hole[now]--;
 85     }
 86   }
 87   if (x > 1 && !a[x - 1][y]) {
 88     int fx = get(ha[now], now), fy = get(ha[now], now - m);
 89     if (fx != fy) {
 90       if (!fx || !fy) ha[now][fx + fy] = 0;
 91       else  ha[now][fx] = fy;
 92       hole[now]--;
 93     }
 94   }
 95   if (y==1 || y==m || x == 1 || x == n) {
 96     int fx = get(ha[now], now);
 97     if (fx) {
 98       ha[now][fx] = 0; hole[now]--;
 99     }
100   }
101  
102   int flag = 1;
103   if (y > 1 && !a[x][y - 1]) {
104     int fx = get(ga[now], now), fy = get(ga[now], now - 1);
105     if (fx != fy) { 
106       ga[now][fx] = fy; 
107       if ((sa[now][fy] += sa[now][fx]) > 1) flag = 0;
108     }
109   }
110   if (x > 1 && !a[x - 1][y]) {
111     int fx = get(ga[now], now), fy = get(ga[now], now - m);
112     if (fx != fy) {
113       ga[now][fx] = fy;
114       if ((sa[now][fy] += sa[now][fx]) > 1) flag = 0;
115     }
116   }
117   if (flag) dfs(now + 1, cnt, con);
118  
119   if (s[x][y] == 'O') return;
120   rep(i, 1, n*m) {
121     fa[now][i] = fa[now - 1][i];
122     ga[now][i] = ga[now - 1][i];
123     sa[now][i] = sa[now - 1][i];
124     ha[now][i] = ha[now - 1][i];
125   }
126   hole[now] = hole[now - 1];
127   a[x][y] = 1;
128   con++;
129   if (y > 1 && a[x][y-1]) {
130     int fx = get(fa[now], now), fy = get(fa[now], now - 1);
131     if (fx != fy) { fa[now][fx] = fy; con--; }
132   }
133   if (x > 1 && a[x-1][y]) {
134     int fx = get(fa[now], now), fy = get(fa[now], now - m);
135     if (fx != fy) { fa[now][fx] = fy; con--; }
136   }
137   dfs(now + 1, cnt + 1, con);
138   a[x][y] = 0;
139 }
140  
141 int main() {
142   scanf("%d%d%d%d", &n, &m, &t, &h);
143   rep(i, 1, n) scanf("%s", s[i] + 1);
144   rep(i, 1, n) rep(j, 1, m) {
145     fa[0][i*m - m + j] = i*m - m + j;
146     ga[0][i*m - m + j] = i*m - m + j;
147     ha[0][i*m - m + j] = i*m - m + j;
148     sa[0][i*m - m + j] = s[i][j] == 'O';
149     hole[0] = 0;
150   }
151   ans = 0;
152   dfs(1, 0, 0);
153   printf("%d\n", ans);
154   return 0;
155 }

 

posted @ 2020-02-08 23:51  一斜星辰酱  阅读(232)  评论(0编辑  收藏  举报