想看官方描述–>传送门
n = 2, artifacts = [[0,0,0,0],[0,1,1,1]], dig = [[0,0],[0,1]]
就是讲,在子集网格中,如果所提供的dig 能把该子网格完全填充,则该子网格就是其中的结果,遍历所有的子网格,得到所有可以被填充的子网格(官方叫组件)
其实也好理解,就是不太好设计。
这个lambda + set.count({}) 直接降本增效
挨个遍历子网格的所有最小单元,如果dig能做到每个都填充,最后retuen true,只要中间出现一个不满足的条件就return false
class Solution {
public:
int digArtifacts(int n, vector<vector<int>>& artifacts, vector<vector<int>>& dig) {
//看了大半天,终于了解大意
//提供的artifacts是描述矩形工件的分布情况,也就是两对角线所包围的内容
//要求从给定挖掘单元格提取工件,意思是若给定的单元格全部覆盖指定工件,既可开挖完整工件
//根据小给定单元格去子网格中占位子网格,如果全部给定单元格占满指定子网格,则可以获取该工件
//怎么塞???
/*
| r1i,c1i |
| r2i,c2i|
artifacts[i] = [r1i, c1i, r2i, c2i]
n = 2, artifacts = [[0,0,0,0],[0,1,1,1]], dig = [[0,0],[0,1]]
dig = [[x1,y1], [x2,y2]]
*/
//和我想的一样,,遍历子网格里头的最小单元,然后把dig一个一个的往里头塞,用hash记录应该会更快一点
//把dig的坐标通过set 传入容器
set<pair<int, int>> s;
for(const auto & d: dig){
int x = d[0], y = d[1];
s.emplace(x, y);
}
//这个lambda是真的牛
auto jude = [&s, &artifacts](int i) ->bool{
//先确定行 再确定列
for(int x = artifacts[i][0]; x <= artifacts[i][2]; ++x){
for(int y = artifacts[i][1]; y <= artifacts[i][3]; ++y){
if(s.count({x, y}) == 0){
return false;
//想一想在这里设为true
}
}
}
//这里设为false 为什么不行
return true;
};
//是这样的必须全部填充才返回true,一旦里面有一部分是dig中所没有的,就不能提取这个部件
int ans = 0;
for(int i = 0; i < artifacts.size();++i){
if(jude(i)){
++ans;
}
}
return ans;
}
};
参考
struct hash_func {
std::size_t operator()(pair<int, int> p) const {
return std::hash<int>()(1000 * p.first + p.second);
};
};
struct equal_func {
bool operator()(pair<int, int> p1, pair<int, int> p2) const {
return p1 == p2;
};
};
unordered_set<pair<int, int>, hash_func, equal_func> us {dig.size()};
auto hash_func = [](pair<int, int> p) -> std::size_t {
return std::hash<int>()(1000 * p.first + p.second);
};
auto equal_func = [](pair<int, int> p1, pair<int, int> p2) -> bool {
return p1 == p2;
};
unordered_set<pair<int, int>, decltype(hash_func), decltype(equal_func)> us{dig.size(), hash_func, equal_func};