Walking Machine
题目大题
在一个
n
∗
m
n*m
n∗m 的矩阵中搜索,每个字符有不同的含义,比如:
W
W
W 表示从(
x
x
x,
y
y
y)可以走到 (
x
−
1
x-1
x−1,
y
y
y)
A
A
A 表示从(
x
x
x,
y
y
y)可以走到 (
x
x
x,
y
−
1
y-1
y−1)
S
S
S 表示从(
x
x
x,
y
y
y)可以走到 (
x
+
1
x+1
x+1,
y
y
y)
D
D
D 表示从(
x
x
x,
y
y
y)可以走到 (
x
x
x,
y
+
1
y+1
y+1)
请求出哪些点会越界,即点坐标(
x
x
x,
y
y
y)
x
x
x < 1 或者
x
x
x >
n
n
n,或者
y
y
y < 1,或者
y
y
y >
m
m
m。
输入格式
输入
n
n
n 和
m
m
m,表示矩阵的大小。
接下来
n
n
n 行,每行
m
m
m 个字符。
输出格式
输出一个整数,表示越界的点的数量。
解题思路
并查集和dfs的综合应用
把矩阵拆分成
n
n
n*
m
m
m个点,记录每个点的位置,然后用并查集的思想,将所有越界的点合并到一个集合,最后将所有的点
f
i
n
d
find
find一下,记录越界的点的数量就是所求的答案。
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e6 + 7, inf = 1e8;
struct node{
int x,y;
char s;
};
node a[maxn];
int fa[maxn], cnt = 0;
char str[1007][1007];
bool inbound(int x, int l, int r)
{
if(x < l || x > r) return false;
return true;
}
void Init(int x) //初始化
{
for(int i = 1; i <= x; i++) fa[i] = i;
}
int Find(int x) //查询,路径压缩
{
if(fa[x] != x) fa[x] = Find(fa[x]);
return fa[x];
}
void Merge(int x, int y) //合并
{
int fax = Find(x), fay = Find(y);
fa[fax] = fay;
}
int main()
{
int n,m;
scanf(" %d%d",&n,&m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
scanf(" %c",&str[i][j]);
a[++cnt] = {i, j, str[i][j]};
}
Init(cnt+1);
for(int i = 1; i <= cnt; i++)
{
int x = a[i].x, y = a[i].y; char s = a[i].s;
int num = (x-1)*m + y;
int tx = 0, ty = 0, tnum = 0;
if(s == 'W') tx = x - 1, ty = y;
if(s == 'A') tx = x, ty = y - 1;
if(s == 'S') tx = x + 1, ty = y;
if(s == 'D') tx = x, ty = y + 1;
if(!inbound(tx, 1, n) || !inbound(ty, 1, m)) Merge(num, cnt+1);
else
{
tnum = (tx - 1)*m + ty;
if(Find(num) != Find(tnum)) Merge(num, tnum);
}
}
int res = 0;
for(int i = 1; i <= cnt; i++)
if(Find(i) == cnt+1) res++;
printf("%d\n",res);
return 0;
}