Scanning line + discretization to calculate the area of a rectangle

We are given a list of (axis-aligned) 2D rectangles rectangles . For rectangle[i] = [x1, y1, x2, y2], where (x1, y1) are the coordinates of the lower left corner of rectangle i, (xi1, yi1) are the coordinates of the lower left corner of the rectangle, (xi2, yi2) are the coordinates of the The coordinates of the upper right corner of the rectangle.

Computes the total area covered by all rectangles in the plane. Any area covered by two or more rectangles should only be counted once. Returns the total area. Since the answer may be too large, return modulo 10^9 + 7.

i ​​​​​​LeetCode link

Ideas:

My first instinct was to calculate the area of ​​all the rectangles, and then subtract the areas where any two intersect. This approach is wrong because each overlap only needs to be subtracted once, and the subtraction may be repeated.

The correct idea for this question is to divide the entire area according to the boundaries of all rectangles, and then calculate the area of ​​the blocks one by one.

step:

  • Store the left and right sides of all rectangles in one array and the top and bottom sides in another array, deduplicate them respectively, and then sort them. The borders obtained at this time are arranged from left to right and from top to bottom, and they divide the entire area into line segments arranged horizontally and vertically, and the line segments form small rectangles.
  • Sort matrix by left bound. This step is to prepare for the next scan from left to right.
  • Create a two-dimensional array with length equal to the number of rectangles. Each of these one-dimensional arrays stores the segmented line segments of the upper and lower boundaries covered by the rectangle. This step is to quickly find the area it covers when traversing the rectangle later.
  • Creates a bool array with length equal to upper and lower bounds -1. Its function is to mark whether a certain area has been covered in this scan.
  • Create a long array with the same length as the bool array to store the total area covered by the area.
  • Traverse the left and right borders from left to right, set all the values ​​of the bool array to false in each loop, traverse all the rectangles covering the border in the loop, and find the upper and lower borders covered by the rectangle through the two-dimensional array, if the corresponding bool value is If false, calculate the area and add it to the corresponding position of the long array, and set the bool value to true.
  • Returns the modulo 1000000007 of the sum of the long array.
class Solution {
public:
    int rectangleArea(vector<vector<int>>& rectangles) {
        long res=0;int i,j,k;
        vector<int> xbound;vector<int> ybound;
        for(i=0;i<rectangles.size();i++)
        {
            xbound.push_back(rectangles[i][0]);
            xbound.push_back(rectangles[i][2]);
            ybound.push_back(rectangles[i][1]);
            ybound.push_back(rectangles[i][3]);
        }
        xbound.erase(unique(xbound.begin(),xbound.end()),xbound.end());
        ybound.erase(unique(ybound.begin(),ybound.end()),ybound.end());
        sort(xbound.begin(),xbound.end());
        sort(ybound.begin(),ybound.end());
        sort(rectangles.begin(),rectangles.end());
        int NumOfLine=ybound.size()-1;
        long area[NumOfLine];
        fill(area,area+NumOfLine,0);
        vector<vector<int>> lines;
        for(i=0;i<rectangles.size();i++)
        {
            vector<int> temp;
            j=0;k=ybound.size()-1;
            while(ybound[j]<rectangles[i][1])
            j++;
            while(ybound[k]>rectangles[i][3])
            k--;
            while(j<k)
                temp.push_back(j++);
            lines.push_back(temp);
        }
        bool flag[NumOfLine];
        for(i=0;i<xbound.size()-1;i++)//i表示扫描线
        {
            fill(flag,flag+NumOfLine,false);
            for(j=0;j<rectangles.size();j++)//j标记矩形
            {
                if(rectangles[j][0]>xbound[i])
                break;
                if(rectangles[j][2]<=xbound[i])
                continue;
                for(int y:lines[j])
                if(!flag[y])
                {
                    area[y]+=(long)(xbound[i+1]-xbound[i])*(ybound[y+1]-ybound[y]);
                    flag[y]=true;
                }
            }/**/
        }
        for(i=0;i<NumOfLine;i++)
        res+=area[i];
        return res%1000000007;
    }
};

Guess you like

Origin blog.csdn.net/qq_43533956/article/details/126911288