想看官方描述–>传送门
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};