问题描述
一块地用一个从 0 开始索引的二维二进制矩阵 block 表示,其中 0 表示空闲地块,1 表示放有障碍物的地块。在每个测试用例中,地的左上角永远是空闲的。一架无人机面向右侧,从左上角开始巡逻。无人机将一直前进,直到抵达的边界或遇到障碍物地块时,无人机将会顺时针旋转 90 度并重复以上步骤,初始位置和无人机飞过的地块都会被它巡逻。若无人机可以持续飞行下去,返回被巡逻到的地块数量。
Java 题解
import java.util.Scanner;
public class Solution{
public static void main(String[] args) {
// 创建一个Scanner对象,用于从标准输入读取数据
Scanner in = new Scanner(System.in);
// 读取二维矩阵的行数和列数
int block_rows = in.nextInt();
int block_cols = in.nextInt();
// 创建一个二维矩阵来存储障碍物和空闲地块的信息
int[][] block = new int[block_rows][block_cols];
for (int i = 0; i < block_rows; i++) {
for (int j = 0; j < block_cols; j++) {
block[i][j] = in.nextInt();
}
}
// 关闭Scanner对象
in.close();
// 创建一个三维布尔数组,记录每个位置的4个方向是否被访问过
boolean[][][] visited_direction = new boolean[block_rows][block_cols][4];
// 创建一个二维布尔数组,记录每个位置是否被访问过
boolean[][] visited_block = new boolean[block_rows][block_cols];
// 初始化方向数组,表示右、下、左、上的方向(顺时针方向变化)
int[] dx = {0, 1, 0, -1};
int[] dy = {1, 0, -1, 0};
// 初始化初始位置和方向
int x = 0, y = 0;
int direction = 0;
// 初始化结果计数器
int result = 0;
// 主循环,直到当前位置的当前方向被访问过
while (!visited_direction[x][y][direction]) {
// 记录当前位置的当前方向已被访问
visited_direction[x][y][direction] = true;
// 如果当前位置未被访问过,则增加结果计数器并记录为已访问
if (!visited_block[x][y]) {
result++;
visited_block[x][y] = true;
}
// 计算下一个位置的坐标
int next_x = x + dx[direction];
int next_y = y + dy[direction];
// 当遇到边界或者障碍物时,寻找下一个可移动的位置
while (next_x < 0 || next_y < 0 || next_x >= block_rows || next_y >= block_cols || block[next_x][next_y] == 1) {
// 顺时针旋转方向
direction = (direction + 1) % 4;
// 重新计算下一个位置的坐标
next_x = x + dx[direction];
next_y = y + dy[direction];
}
// 更新当前位置和方向
x = next_x;
y = next_y;
}
// 输出结果
System.out.printf(String.valueOf(result));
}
}