矩形面积 III
现给该题做一次修改,只计算那些有重叠的矩形,即如果有一个矩形不和其它矩形重叠【有面积意义,线段的重叠和点的重叠无】,那么就不计算它的面积。
#include<iostream> #include<vector> #include<tuple> #include<algorithm> #include<set> using namespace std; const static int MOD = 1000000007; const static int OPEN = 0; const static int CLOSE = 1; // 计算宽度:其实就是不断累加更大的x的差值即可 int QueryWidth(multiset<pair<int, int>>& activate) { int res = 0; int maxX = -1; for (auto x : activate) { maxX = max(maxX, x.first); // 如果x变大了,则计算差值累加更大的宽度 res += max(0, x.second - maxX); // 不断更新最大x maxX = max(maxX, x.second); } return res; } void QueryValid(vector<vector<int>>& rectangles,multiset<pair<pair<int, int>, int>>& activate, const vector<int>& out_edge, set<int>& valid) { for (auto &x : activate) { // 入边的x是不是 和目前的出边有交叉 if (x.second != out_edge[4]) { if ((x.first.first < out_edge[3] && x.first.second > out_edge[3]) || (x.first.first < out_edge[2] && x.first.second > out_edge[2]) || (x.first.first >= out_edge[2] && x.first.second <= out_edge[3]) || (x.first.first < out_edge[2] && x.first.second > out_edge[3])) { if (out_edge[0] > rectangles[x.second][1]) { valid.insert(out_edge[4]); valid.insert(x.second); } } } } } int rectangleArea(vector<vector<int>>& rectangles, set<int> & valid) { if (valid.size() == 0) return 0; vector<vector<int>> rec; int cnt = 0; for (auto v : rectangles) { if (valid.find(cnt)!= valid.end()) { rec.push_back({ v[1], OPEN, v[0], v[2] }); rec.push_back({ v[3], CLOSE, v[0], v[2] }); } cnt++; } // 排序从下到上来扫描 sort(rec.begin(), rec.end()); // 存储面积和 int res = 0; // 初始化第一个y的位置 int lastY = rec[0][0]; // 当前需要计算的面积横坐标 [x1,x2] // 扫描过程中 对于每次OPEN则插入,CLOSE则删除 multiset<pair<int, int>> activate; for (const vector<int> r : rec) { int y = r[0]; int state = r[1]; int x1 = r[2]; int x2 = r[3]; // 累加面积 res = (res + (long long)QueryWidth(activate) * (y - lastY)) % MOD; // 更新上一个y坐标 lastY = y; // 对于每次OPEN则插入,CLOSE则删除 if (state == OPEN) { activate.insert(make_pair(x1, x2)); } else { activate.erase(activate.find(pair<int, int>{x1, x2})); } } return res; } bool ispoint_in_rectangle(int px, int py, int x0, int y0, int x1, int y1) { if ((px >= x0 && px <= y0) && (py >= y0 && py <= y1)) return true; else return false; } set<int> setvalidrectangle(vector<vector<int>>& rectangles) { vector<vector<int>> rec; int cnt = 0; for (auto v : rectangles) { rec.push_back({ v[1], OPEN, v[0], v[2],cnt }); rec.push_back({ v[3], CLOSE, v[0], v[2],cnt }); cnt++; } // 排序从下到上来扫描 sort(rec.begin(), rec.end()); // 存储有效的矩形 set<int> valid; // 初始化第一个y的位置 int lastY = rec[0][0]; // // 扫描过程中 对于每次OPEN则插入,CLOSE则删除 multiset<pair<pair<int, int>,int>> activate; //入边的x0 x1 矩形的高度 for (const vector<int> r : rec) { int y = r[0]; int state = r[1]; int x1 = r[2]; int x2 = r[3]; int belong = r[4]; if (state == OPEN) { activate.insert(make_pair(make_pair(x1, x2), belong)); } else { //当前出边数据 y state x1 x2 belong QueryValid(rectangles,activate, r, valid); activate.erase(activate.find(make_pair(make_pair(x1, x2), belong))); } } return valid; } int main() { vector<vector<int>> A = { {0,0,2,2}, {1,1,4,3}, {2,4,4,7}, {2,5,3,6} }; vector<vector<int>> B = { {0,0,1,1}, {1,1,2,2}, {1,0,2,1}}; set<int> valid = setvalidrectangle(B); int ret = rectangleArea(B, valid); cout << ret << endl; }