题目链接点这里
题意是你有 n 个盒子,每个盒子有一个状态 status[i],表示盒子是否打开。每个盒子里面有一些糖果 candies[i],以及一些钥匙 keys[i] 和一些其他盒子 containedBoxes[i]。你最初拥有一些盒子 initialBoxes,你可以通过打开这些盒子来获得里面的糖果和钥匙。钥匙可以用来打开其他盒子,而其他盒子里面可能也有糖果和钥匙。你需要计算你最多能获得多少糖果。
解题思路
这道题目可以使用BFS来解决。首先建立以下数组:
have[i]
:表示我们是否拥有第 i 个盒子。
open[i]
:表示第 i 个盒子是否已经被打开。
visited[i]
:表示第 i 个盒子是否已经被访问过。
我们首先遍历 initialBoxes,将我们拥有的盒子标记为 have[i] = true
,并且如果盒子是打开的 status[i] == 1
,我们就将其加入队列 q 中,并标记为已访问。
然后我们开始BFS。遍历队列中的盒子,对于每个盒子,我们首先将其中的钥匙对应的盒子标记为打开状态 open[keys[a][i]] = true
。如果这个盒子我们之前已经拥有 have[keys[a][i]] == true
,并且还没有被访问过,我们就将其加入队列中。
接着,我们遍历当前盒子中包含的其他盒子,将其标记为拥有 have[containedBoxes[a][i]] = true
。如果这些盒子已经被打开并且还没有被访问过,我们也将其加入队列中。
最后,我们将当前盒子中的糖果数加到 maxx 中,表示我们获得了这些糖果(我们能获得的最大糖果数就是我们能打开的所有箱子里的糖果数之和)。
ac代码如下:
class Solution {
public:int maxCandies(vector<int>& status, vector<int>& candies, vector<vector<int>>& keys, vector<vector<int>>& containedBoxes, vector<int>& initialBoxes) {int n = status.size();vector <bool> have(n, false), open(n, false), visited(n, false); // 初始化状态数组,have表示拥有这个箱子,open代表有这个箱子的钥匙/箱子是打开的,visited表示被访问过for(int i = 0; i < n; i++){if(status[i] == 1) open[i] = true;}queue <int> q;for(auto& i : initialBoxes){have[i] = true;if(open[i] == true){q.push(i);visited[i] = true; // 如果盒子的初始状态是打开的,则标记为访问过}}int maxx = 0; // 初始化能得到的最大糖果数while(!q.empty()){ // 进行bfsint a = q.front();q.pop();for(int i = 0; i < keys[a].size(); i++){ // 判断得到哪些盒子的钥匙open[keys[a][i]] = true;if(have[keys[a][i]] == true && !visited[keys[a][i]]){q.push(keys[a][i]);visited[keys[a][i]] = true;}}for(int i = 0; i < containedBoxes[a].size(); i++){ // 判断我们拥有哪些盒子have[containedBoxes[a][i]] = true;if(open[containedBoxes[a][i]] == true && !visited[containedBoxes[a][i]]){q.push(containedBoxes[a][i]);visited[containedBoxes[a][i]] = true;} }maxx += candies[a]; // 累加当前盒子中的糖果数}return maxx;}
};