Skip to content

feat: add solutions to lc problem: No.3568 #4455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 248 additions & 5 deletions solution/3500-3599/3568.Minimum Moves to Clean the Classroom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,32 +108,275 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3568.Mi

<!-- solution:start -->

### 方法一
### 方法一:BFS

我们可以使用广度优先搜索(BFS)来解决这个问题。首先,我们需要找到学生的起始位置,并记录所有垃圾的位置。然后,我们可以使用 BFS 来探索从起始位置出发的所有可能路径,同时跟踪当前能量和已收集的垃圾。

在 BFS 中,我们需要维护一个状态,包括当前的位置、剩余的能量和已收集的垃圾掩码。我们可以使用一个队列来存储这些状态,并使用一个集合来记录已经访问过的状态,以避免重复访问。

我们从起始位置开始,尝试向四个方向移动。如果移动到一个垃圾单元格,我们将更新已收集的垃圾掩码。如果移动到一个重置区域,我们将能量恢复到最大值。每次移动都会消耗 1 单位能量。

如果我们在 BFS 中找到了一个状态,其中已收集的垃圾掩码为 0(表示所有垃圾都已收集),则返回当前的移动次数。如果 BFS 完成后仍未找到这样的状态,则返回 -1。

时间复杂度 $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$,空间复杂度 $O(m \times n \times \textit{energy} \times 2^{\textit{count}})$,其中 $m$ 和 $n$ 分别是网格的行数和列数,而 $\textit{count}$ 是垃圾单元格的数量。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def minMoves(self, classroom: List[str], energy: int) -> int:
m, n = len(classroom), len(classroom[0])
d = [[0] * n for _ in range(m)]
x = y = cnt = 0
for i, row in enumerate(classroom):
for j, c in enumerate(row):
if c == "S":
x, y = i, j
elif c == "L":
d[i][j] = cnt
cnt += 1
if cnt == 0:
return 0
vis = [
[[[False] * (1 << cnt) for _ in range(energy + 1)] for _ in range(n)]
for _ in range(m)
]
q = [(x, y, energy, (1 << cnt) - 1)]
vis[x][y][energy][(1 << cnt) - 1] = True
dirs = (-1, 0, 1, 0, -1)
ans = 0
while q:
t = q
q = []
for i, j, cur_energy, mask in t:
if mask == 0:
return ans
if cur_energy <= 0:
continue
for k in range(4):
x, y = i + dirs[k], j + dirs[k + 1]
if 0 <= x < m and 0 <= y < n and classroom[x][y] != "X":
nxt_energy = (
energy if classroom[x][y] == "R" else cur_energy - 1
)
nxt_mask = mask
if classroom[x][y] == "L":
nxt_mask &= ~(1 << d[x][y])
if not vis[x][y][nxt_energy][nxt_mask]:
vis[x][y][nxt_energy][nxt_mask] = True
q.append((x, y, nxt_energy, nxt_mask))
ans += 1
return -1
```

#### Java

```java

class Solution {
public int minMoves(String[] classroom, int energy) {
int m = classroom.length, n = classroom[0].length();
int[][] d = new int[m][n];
int x = 0, y = 0, cnt = 0;
for (int i = 0; i < m; i++) {
String row = classroom[i];
for (int j = 0; j < n; j++) {
char c = row.charAt(j);
if (c == 'S') {
x = i;
y = j;
} else if (c == 'L') {
d[i][j] = cnt;
cnt++;
}
}
}
if (cnt == 0) {
return 0;
}
boolean[][][][] vis = new boolean[m][n][energy + 1][1 << cnt];
List<int[]> q = new ArrayList<>();
q.add(new int[] {x, y, energy, (1 << cnt) - 1});
vis[x][y][energy][(1 << cnt) - 1] = true;
int[] dirs = {-1, 0, 1, 0, -1};
int ans = 0;
while (!q.isEmpty()) {
List<int[]> t = q;
q = new ArrayList<>();
for (int[] state : t) {
int i = state[0], j = state[1], curEnergy = state[2], mask = state[3];
if (mask == 0) {
return ans;
}
if (curEnergy <= 0) {
continue;
}
for (int k = 0; k < 4; k++) {
int nx = i + dirs[k], ny = j + dirs[k + 1];
if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx].charAt(ny) != 'X') {
int nxtEnergy = classroom[nx].charAt(ny) == 'R' ? energy : curEnergy - 1;
int nxtMask = mask;
if (classroom[nx].charAt(ny) == 'L') {
nxtMask &= ~(1 << d[nx][ny]);
}
if (!vis[nx][ny][nxtEnergy][nxtMask]) {
vis[nx][ny][nxtEnergy][nxtMask] = true;
q.add(new int[] {nx, ny, nxtEnergy, nxtMask});
}
}
}
}
ans++;
}
return -1;
}
}
```

#### C++

```cpp

class Solution {
public:
int minMoves(vector<string>& classroom, int energy) {
int m = classroom.size(), n = classroom[0].size();
vector<vector<int>> d(m, vector<int>(n, 0));
int x = 0, y = 0, cnt = 0;
for (int i = 0; i < m; ++i) {
string& row = classroom[i];
for (int j = 0; j < n; ++j) {
char c = row[j];
if (c == 'S') {
x = i;
y = j;
} else if (c == 'L') {
d[i][j] = cnt;
cnt++;
}
}
}
if (cnt == 0) {
return 0;
}
vector<vector<vector<vector<bool>>>> vis(m, vector<vector<vector<bool>>>(n, vector<vector<bool>>(energy + 1, vector<bool>(1 << cnt, false))));
queue<tuple<int, int, int, int>> q;
q.emplace(x, y, energy, (1 << cnt) - 1);
vis[x][y][energy][(1 << cnt) - 1] = true;
vector<int> dirs = {-1, 0, 1, 0, -1};
int ans = 0;
while (!q.empty()) {
int sz = q.size();
while (sz--) {
auto [i, j, cur_energy, mask] = q.front();
q.pop();
if (mask == 0) {
return ans;
}
if (cur_energy <= 0) {
continue;
}
for (int k = 0; k < 4; ++k) {
int nx = i + dirs[k], ny = j + dirs[k + 1];
if (nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X') {
int nxt_energy = classroom[nx][ny] == 'R' ? energy : cur_energy - 1;
int nxt_mask = mask;
if (classroom[nx][ny] == 'L') {
nxt_mask &= ~(1 << d[nx][ny]);
}
if (!vis[nx][ny][nxt_energy][nxt_mask]) {
vis[nx][ny][nxt_energy][nxt_mask] = true;
q.emplace(nx, ny, nxt_energy, nxt_mask);
}
}
}
}
ans++;
}
return -1;
}
};
```

#### Go

```go

func minMoves(classroom []string, energy int) int {
m, n := len(classroom), len(classroom[0])
d := make([][]int, m)
for i := range d {
d[i] = make([]int, n)
}
x, y, cnt := 0, 0, 0
for i := 0; i < m; i++ {
row := classroom[i]
for j := 0; j < n; j++ {
c := row[j]
if c == 'S' {
x, y = i, j
} else if c == 'L' {
d[i][j] = cnt
cnt++
}
}
}
if cnt == 0 {
return 0
}

vis := make([][][][]bool, m)
for i := range vis {
vis[i] = make([][][]bool, n)
for j := range vis[i] {
vis[i][j] = make([][]bool, energy+1)
for e := range vis[i][j] {
vis[i][j][e] = make([]bool, 1<<cnt)
}
}
}
type state struct {
i, j, curEnergy, mask int
}
q := []state{{x, y, energy, (1 << cnt) - 1}}
vis[x][y][energy][(1<<cnt)-1] = true
dirs := []int{-1, 0, 1, 0, -1}
ans := 0

for len(q) > 0 {
t := q
q = []state{}
for _, s := range t {
i, j, curEnergy, mask := s.i, s.j, s.curEnergy, s.mask
if mask == 0 {
return ans
}
if curEnergy <= 0 {
continue
}
for k := 0; k < 4; k++ {
nx, ny := i+dirs[k], j+dirs[k+1]
if nx >= 0 && nx < m && ny >= 0 && ny < n && classroom[nx][ny] != 'X' {
var nxtEnergy int
if classroom[nx][ny] == 'R' {
nxtEnergy = energy
} else {
nxtEnergy = curEnergy - 1
}
nxtMask := mask
if classroom[nx][ny] == 'L' {
nxtMask &= ^(1 << d[nx][ny])
}
if !vis[nx][ny][nxtEnergy][nxtMask] {
vis[nx][ny][nxtEnergy][nxtMask] = true
q = append(q, state{nx, ny, nxtEnergy, nxtMask})
}
}
}
}
ans++
}
return -1
}
```

<!-- tabs:end -->
Expand Down
Loading