题意:
给出一个 n ∗ m n * m n∗m 的矩阵,KaTeX parse error: Expected 'EOF', got '#' at position 3: ' #̲ ' 代表黑色方格,$’ . ’ $代表白色方格,现在可以在任意方格上摆放任意个单向磁铁,磁铁具有的一个性质是:
每秒钟 N N N 极磁铁会向同行或同列的 S S S 极磁铁靠拢,但 S S S 极磁铁不会移动,需要构造一种方案,使得:
无论如何移动, N N N 极磁铁都无法到达白色方格,存在一种移动方案,使得 N N N 极磁铁可以遍历所有黑色方格,每一行、每一列至少存在一个 S S S 极磁铁 N N N 极磁铁的个数尽可能少。
输出最少的 N N N 极磁铁的个数。
先判断(是否有空行)异或(是否有空列),如果异或值为真则不行。然后判断是否出现 KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲... .#(即两个 KaTeX parse error: Expected 'EOF', got '#' at position 1: #̲ 中间夹了 . . . 的情况),出现就不行。
其他情况就输出联通块个数即可。
AC代码:
const int N = 1e3 + 10;
char s[N][N];
int n, m, ans;
bool dx[N], dy[N];
bool ok[N][N], vis[N][N];
bool flag;
void dfs(int x, int y)
{
if (vis[x][y] || s[x][y] != '#')
return;
vis[x][y] = 1;
if (x > 0)
dfs(x - 1, y);
if (y > 0)
dfs(x, y - 1);
if (x < n - 1)
dfs(x + 1, y);
if (y < m - 1)
dfs(x, y + 1);
}
int main()
{
sdd(n, m);
rep(i, 0, n - 1)
ss(s[i]);
rep(i, 0, n - 1)
{
rep(j, 0, m - 1)
{
if (s[i][j] == '#')
{
if (dx[i] && j > 0 && s[i][j - 1] == '.')
{
puts("-1");
return 0;
}
if (dy[j] && i > 0 && s[i - 1][j] == '.')
{
puts("-1");
return 0;
}
dx[i] = dy[j] = 1;
}
}
}
rep(i, 0, n - 1)
{
rep(j, 0, m - 1)
{
if (s[i][j] == '.' && (dx[i] || dy[j]))
ok[i][j] = 1;
}
}
mem(dx, 0);
mem(dy, 0);
rep(i, 0, n - 1)
{
rep(j, 0, m - 1)
{
if (ok[i][j] == 0)
{
dx[i] = dy[j] = 1;
}
}
}
rep(i, 0, n - 1)
{
if (!dx[i])
{
puts("-1");
return 0;
}
}
rep(j, 0, m - 1)
{
if (!dy[j])
{
puts("-1");
return 0;
}
}
ans = 0;
rep(i, 0, n - 1)
{
rep(j, 0, m - 1)
{
if (!vis[i][j] && s[i][j] == '#')
{
ans++;
dfs(i, j);
}
}
}
pd(ans);
return 0;
}