ABC219 E - Moat(dfs)
目录
Description
有一个 \(4*4\) 的地图,要求将所有的 \(1\) 围起来,求有多少种方法
必须保证:
1.线与线之间不可以交叉
2.每个夹角必须是直角
State
Input
1 0 0 0
0 0 1 0
0 0 0 0
1 0 0 0
Output
1272
Solution
题目说了一圈,每个夹角必须是直角,可以将题目转化一下,我们将围起来的图形标记为 \(1\),没有围起来的图形标记为 \(0\),那么只要保证所有的 \(1\) 被 \(0\) 包围起来,那么构成一种答案;
那么该如何实现呢? 一共有 \(16\) 个村庄,将其看成一维的不就是有 \(2^{16}\) 种情况吗
还有一种特殊情况,就是 \(1\) 到达了边界也是有可能成立的,但是可以在这个 \(4*4\) 的地图周围全部标记为 \(0\) 就可以避免了
Code
int n, m, k, _;
int a[10][10];
int vis[10][10];
int have1, ok, have0;
int mp[10][10];
pii calc(int x)
{
return make_pair(x / 4 + 1, x % 4 + 1);
}
void build(int x)
{
for(int i = 0; i < 16; i ++){
int id = x & (1 << i);
pii ans = calc(i);
// dbg(ans.fi);
// dbg(ans.se);
if(id){
a[ans.fi][ans.se] = 1;
}
else{
a[ans.fi][ans.se] = 0;
}
}
}
bool judge(int x, int y)
{
if(x < 0 || x > 5 || y < 0 || y > 5) return 0;
return 1;
}
void dfs1(int x, int y, int bit)
{
mp[x][y] = 1;
for(int i = 0; i < 4; i ++){
int nx = x + dx[i], ny = y + dy[i];
if(judge(nx, ny) && mp[nx][ny] == 0 && a[nx][ny] == bit) dfs1(nx, ny, bit);
}
}
void clear()
{
rep(i, 0, 5){
rep(j, 0, 5){
mp[i][j] = 0;
}
}
}
signed main()
{
//IOS;
//dbg(1 << 16);
for(int i = 1; i <= 4; i ++){
for(int j = 1; j <= 4; j ++){
sd(vis[i][j]);
}
}
int ans = 0;
for(int k = 0; k < (1 << 16); k ++){
build(k);
// for(int i = 0; i <= 5; i ++){
// for(int j = 0; j <= 5; j ++){
// cout << a[i][j] << " ";
// }
// cout << endl;
// }
ok = 1;
for(int i = 1; i <= 4; i ++){
for(int j = 1; j <= 4; j ++){
if(vis[i][j] && a[i][j] == 0) ok = 0;
}
}
// dbg(ok);
have0 = have1 = 0;
for(int i = 0; i <= 5; i ++){
for(int j = 0; j <= 5; j ++){
if(mp[i][j] == 0){
dfs1(i, j, a[i][j]);
if(a[i][j]) have1 ++;
else have0 ++;
}
}
}
clear();
if(ok && have1 == 1 && have0 == 1) ans ++;
}
pd(ans);
// PAUSE;
return 0;
}

浙公网安备 33010602011771号