LeetCode 1001 网格照明
题目链接:LeetCode 1001 网格照明
题目大意:
题解:
假设一盏灯的坐标为\((x_i,y_i)\),那么它所在的行的数值为\(x_i\),列的数值为\(y_i\),正对角线的数值为\(x_i-y_i\),反对角线的数值为\(x_i+y_i\)。确定某一直线的唯一数值标识后,我们就可以通过哈希表来记录某一直线所拥有的灯的数目。
遍历\(lamps\),将当前遍历到的灯所在的行,列和正/反对角线拥有灯的数目分别加一,该过程需要进行去重。
遍历\(queries\),判断当前查询点所在的行,列和正/反对角线是否有灯,如果有,则置\(1\),即该点在查询时是被照亮的。然后进行关闭操作,查找查询点所在的八近邻点及它本身是否有灯,如果有,将该点所在的行,列和正/反对角线的灯数目分别减一,并且将灯从网格中去掉。
class Solution {
private:
vector<vector<int>> dirs = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 0}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
public:
vector<int> gridIllumination(int n, vector<vector<int>>& lamps, vector<vector<int>>& queries) {
unordered_map<int, int> row, col, diagonal, antiDiagonal;
auto hash_pii = [](const pair<int, int>& p) -> size_t {
static hash<long long> hash_ll;
return hash_ll(p.first + (static_cast<long long>(p.second) << 32));
};
unordered_set<pair<int, int>, decltype(hash_pii)> lights(0, hash_pii);
for (auto& lamp : lamps) {
if (!lights.count({lamp[0], lamp[1]})) {
lights.insert({lamp[0], lamp[1]});
open(row, col, diagonal, antiDiagonal, lamp);
}
}
vector<int> ans;
for (auto& query : queries) {
if (isLight(row, col, diagonal, antiDiagonal, query)) {
ans.emplace_back(1);
} else {
ans.emplace_back(0);
}
for (auto& dir : dirs) {
int x = query[0] + dir[0], y = query[1] + dir[1];
if (x >= 0 && x < n && y >= 0 && y < n && lights.count({x, y})) {
lights.erase({x, y});
vector<int> lamp = {x, y};
close(row, col, diagonal, antiDiagonal, lamp);
}
}
}
return ans;
}
bool isLight(unordered_map<int, int>& row, unordered_map<int, int>& col, unordered_map<int, int>& diagonal, unordered_map<int, int>& antiDiagonal, vector<int>& query) {
return (row.count(query[0]) && row[query[0]]) || (col.count(query[1]) && col[query[1]]) || (diagonal.count(query[0] - query[1]) && diagonal[query[0] - query[1]]) || (antiDiagonal.count(query[0] + query[1]) && antiDiagonal[query[0] + query[1]]);
}
void open(unordered_map<int, int>& row, unordered_map<int, int>& col, unordered_map<int, int>& diagonal, unordered_map<int, int>& antiDiagonal, vector<int>& lamp) {
row[lamp[0]]++;
col[lamp[1]]++;
diagonal[lamp[0] - lamp[1]]++;
antiDiagonal[lamp[0] + lamp[1]]++;
}
void close(unordered_map<int, int>& row, unordered_map<int, int>& col, unordered_map<int, int>& diagonal, unordered_map<int, int>& antiDiagonal, vector<int>& lamp) {
row[lamp[0]]--;
col[lamp[1]]--;
diagonal[lamp[0] - lamp[1]]--;
antiDiagonal[lamp[0] + lamp[1]]--;
}
};