Description
流浪猫布满城市的每一个角落,非常影响市容市貌,作为城市聘请的抓猫者,你有一种捕捉器,一定可以捕捉到所有走到里面的猫,更加幸运的是你有一个非常厉害的动物心理学家,他可以预测猫在不同位置的行走方向(共有东、西、南、北四种情况)
为了节约经费,问你最少需要多少个捕捉器才能把所有的猫都抓住。
Input
输入第一行包含两个整数N和M(1<=N,M<=1000),表示城市被划分成N×M的网格。接下来N行,每行包含M个字符“E”、“W”、“S”、“N”代表东、西、南、北4个方向,表示当猫在该位置的行走方向,保证猫不会走出城市区域。
Output
输出一个整数表示最少需要的捕捉器数。
Sample Input
3 4
SWWW
SEWN
EEEN
Sample Output
2
Data Constraint
Hint
【数据说明】
40% 1<=N,M<=4
100% 1<=N,M<=1000
做法:连边后用并查集将可联通的缩成一个点,最后统计多少个可联通的;
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 1007
#define ll long long
#define rep(i,a,b) for (int i = a; i <= b; i++)
using namespace std;
int n, m, to[N * N], f[N * N], ans;
bool b[N * N];
int find(int x)
{
if (f[x] == 0) return x;
f[x] = find(f[x]);
return f[x];
}
int main()
{
scanf("%d%d", &n, &m);
char ch = getchar();
rep(i, 1, n)
{
rep(j, 1, m)
{
ch = getchar();
if (ch == 'S') to[m * (i - 1) + j] = m * i + j;
if (ch == 'N') to[m * (i - 1) + j] = m * (i - 2) + j;
if (ch == 'W') to[m * (i - 1) + j] = m * (i - 1) + j - 1;
if (ch == 'E') to[m * (i - 1) + j] = m * (i - 1) + j + 1;
}
ch = getchar();
}
rep(i, 1, n * m)
{
int q = find(i), p = find(to[i]);
if (q != p) f[q] = p;
}
rep(i, 1, n * m)
{
int q = find(f[i]);
b[q] = 1;
}
rep(i, 1, n * m)
{
if (b[i]) ans++;
}
printf("%d", ans);
}