Loading

2022.10.26 总结

1. 逐月 P5132

逐月 P5132

题意

有一个 \(n \times n\) 的房间,Bessie 在 \((1, 1)\) 处,这个房间是亮着灯的。

Bessie 害怕黑暗,她想要打开尽可能多的灯。

在一些房间中,她可以找到打开别的房间灯的开关,并且,她只能往自己周围四个房间走。

请你求出 Bessie 最多能打开多少个房间的灯。

思路

100 分

首先,这个题目很明显,是一个搜索。

那么,就需要考虑状态和转移是什么的问题了。

先看状态,很明显,是 \((x, y)\),也就是坐标。有一种转移很明显,就是往上下左右做转移,但是一个房间能否走不只是要看能不能走到,还要看有没有亮灯,所以这是第二种转移。

第一种转移实现很简单,主要是第二种。

首先得清楚一件事,你是绝对不能往回走的,因为如果可以往回走,那你就能这样走:\((1, 1)\) -> \((1, 2)\) -> \((1, 1)\) -> \((1, 2)\) -> \((1, 1) \dots\)

但是如果是这样的一个样例的话:

3 6
1 1 1 2
2 1 2 2
1 1 1 3
2 3 3 1
1 3 1 2
1 3 2 1

在走到 \((1, 3)\) 时,会触发 \((2, 1)\) 的开关,但是,要想走到 \((2, 1)\),就得先到 \((1, 2)\),再到 \((1, 1)\),再去 \((2, 1)\),而点又是不能重复走的,所以,你需要知道:你走过的点都是可以再次走到的。根据这个,就可以得到解决问题的方法:枚举每个会被触发的房间,判断四周是否有走到过的房间,如果有,这个房间就是可以被走到的。

直接搜索就可以了。

时间复杂度

状态图遍历,每个房间只会被遍历一遍,\(O(n ^ 2)\)

枚举被触发的房间,用 vector,\(O(m)\)

总时间复杂度为 \(O(n ^ 2 + m)\)

空间复杂度

\(n ^ 2\) 个 vector,\(O(n ^ 2)\)

vector 总共会存放 \(m\) 个坐标,\(O(m)\)

总空间复杂度为 \(O(n ^ 2 + m)\)

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 110;

const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};

int n, m, ans;
bool f[N][N], vis[N][N];

struct C {
  int x, y;
};

vector<C> v[N][N];

void dfs(int x, int y) {
  if (x < 1 || x > n || y < 1 || y > n || !f[x][y] || vis[x][y]) {
    return ;
  }
  vis[x][y] = 1;
  for (int i = 0; i < v[x][y].size(); i++) {
    bool flag = 0;
    int xx = v[x][y][i].x, yy = v[x][y][i].y;
    f[xx][yy] = 1;
    for (int j = 0; j < 4; j++) {
      int nx = xx + dx[j], ny = yy + dy[j];
      if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && vis[nx][ny]) {
        flag = 1;
        break;
      }
    }
    if (flag) {
      dfs(xx, yy);
    }
  }
  for (int i = 0; i < 4; i++) {
    dfs(x + dx[i], y + dy[i]);
  }
}

int main() {
  freopen("lightson.in", "r", stdin);
  freopen("lightson.out", "w", stdout);
  cin >> n >> m;
  while (m--) {
    int x, y, a, b;
    cin >> x >> y >> a >> b;
    v[x][y].push_back({a, b});
  }
  f[1][1] = 1;
  dfs(1, 1);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      ans += f[i][j];
    }
  }
  cout << ans;
  return 0;
}
posted @ 2023-03-02 22:45  chengning0909  阅读(9)  评论(0编辑  收藏  举报