🍑 算法题解专栏
🍑 百练OJ 城堡问题
输入
4
7
11 6 11 6 3 10 6
7 9 6 13 5 15 5
1 10 12 7 13 7 5
13 11 10 8 10 12 13
输出
5
9
🍑 flood-fill 记录遍历的节点数
🍑 颠倒数组存图
🍑 位移矢量要和题意描述的方向一致
import java.util.Scanner;
public class Main
{
static int N = 55, n, m;
static int[][] g = new int[N][N];
static boolean[][] st = new boolean[N][N];
static Node[] q = new Node[N * N];// 队列一定要能涵盖所有的点
// 按照题意顺序初始化位移表 西北东南(注意是颠倒数组)
static int[] dx = { 0, -1, 0, 1 };
static int[] dy = { -1, 0, 1, 0 };
static class Node
{
int x;
int y;
public Node(int x, int y)
{
super();
this.x = x;
this.y = y;
}
}
static int bfs(int sx, int sy)
{
st[sx][sy] = true;
// System.out.println(sx + " " + sy);
int area = 0;
int hh = 0;
int tt = -1;
q[++tt] = new Node(sx, sy);
while (hh <= tt)
{
Node t = q[hh++];// 队头出队
area++;// 出队一个,面积+1
int x = t.x;
int y = t.y;
for (int i = 0; i < 4; i++)// 四联通
{
int xx = x + dx[i];
int yy = y + dy[i];
if (xx < 0 || xx >= n || yy < 0 || yy >= m)// 非法越界
continue;
if (st[xx][yy])// 避免重复遍历
continue;
if ((g[x][y] >> i & 1) == 1)// 墙,注意这里是当前点{x,y}的四周墙的值
continue;
st[xx][yy] = true;
q[++tt] = new Node(xx, yy);
}
}
return area;
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
g[i][j] = sc.nextInt();// 输入的是周围是墙还是空地(并不会输入墙)
int cnt = 0;
int area = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (!st[i][j])
{
area = Math.max(area, bfs(i, j));
cnt++;
}
System.out.println(cnt);
System.out.println(area);
}
}