记网易笔试一道题

 

 矩形面积 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;
    
}

 

posted @ 2022-08-27 23:31  PiaYie  阅读(18)  评论(0编辑  收藏  举报