美文网首页
223. Rectangle Area (M)

223. Rectangle Area (M)

作者: Ysgc | 来源:发表于2020-11-22 10:47 被阅读0次

Find the total area covered by two rectilinear rectangles in a 2D plane.

Each rectangle is defined by its bottom left corner and top right corner as shown in the figure.

Example:

<pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13px; margin-top: 0px; margin-bottom: 1em; overflow: auto; background: var(--dark-bg); border-color: rgb(51, 51, 51); color: var(--font) !important; padding: 10px 15px; line-height: 1.6; border-radius: 3px; white-space: pre-wrap;">Input: A = -3, B = 0, C = 3, D = 4, E = 0, F = -1, G = 9, H = 2
Output: 45</pre>

Note:

Assume that the total area is never beyond the maximum possible value of int.


这道题抛开long的坑不谈,我一开始就想错方向了,试图去分类讨论,找哪些点,有几个点被互相包括,1个点包括的话怎么算,2个点包括怎么办, 4个点包括怎么办,0个点包括怎么办。
结果搞不完的edge cases。比如inclusion函数得是闭区间,否则会判断出0个点包含。但是有可能有left在right里面,但是left的边缘也在right边缘的情况,需要开区间。
就算都修复完成,还有一个case是十字交叉... 真修复不完了!
所以还是感觉写代码量太大的情况下,早点看答案!

自己写的答案:

class Solution {
public:
    int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
        int cross_area = max(
            CrossArea(A,B,C,D,E,F,G,H), CrossArea(E,F,G,H,A,B,C,D)
        );
        // cout << CrossArea(A,B,C,D,E,F,G,H) << ", " << CrossArea(E,F,G,H,A,B,C,D) << endl;
        long ans = (C-A)*(D-B) + (G-E)*(H-F) - cross_area;
        return ans;
    }
    int CrossArea (int A, int B, int C, int D, int E, int F, int G, int H) {
        vector<pair<int,int>> points_left = FourPoints(A,B,C,D);
        vector<pair<int,int>> points_right = FourPoints(E,F,G,H);
        
        vector<pair<int,int>> right_included;
        for (auto& p:points_left) {
            if (Inclusion(p,E,G,F,H)) {
                right_included.push_back(p);
            }
        }
        int right_inclusion_num = right_included.size();
        
        if (right_inclusion_num == 4) {
            return (C-A)*(D-B);
        }
        else if (right_inclusion_num == 1) {
            for (auto& p:points_right) {
                if (Inclusion(p,A,C,B,D)) {
                    return abs(p.first-right_included[0].first)
                            *abs(p.second-right_included[0].second);
                }
            }
        }
        else if (right_inclusion_num == 2) {
            int x_min = min(right_included[0].first, right_included[1].first);
            int x_max = max(right_included[0].first, right_included[1].first);
            int y_min = min(right_included[0].second, right_included[1].second);
            int y_max = max(right_included[0].second, right_included[1].second);
            if (x_min == x_max) {
                for (auto& p:points_right) {
                    if (Inclusion(p,A,C,INT_MIN,INT_MAX)) {
                        return (y_max-y_min)*abs(x_min-p.first);
                    }
                }
            }
            else if (y_min == y_max) {
                for (auto& p:points_right) {
                    if (Inclusion(p,INT_MIN,INT_MAX,B,D)) {
                        return (x_max-x_min)*abs(y_min-p.second);
                    }
                }
            }
        }
        
        return 0;
    }
    vector<pair<int,int>> FourPoints(int& A, int& B, int& C, int& D) {
        return {{A,B}, {C,B}, {C,D}, {A,D}};
    }
    bool Inclusion(pair<int,int>& point, int x_min_bound, int x_max_bound, int y_min_bound, int y_max_bound) {
        return (
            point.first >= x_min_bound and 
            point.first <= x_max_bound and 
            point.second >= y_min_bound and 
            point.second <= y_max_bound
        );
    }
};

虽然完全想偏了,但是其中几个语法错误需要思考:

  • 函数foo(int& a) 的输入不能是rvalue,比如foo(1)就完全错了!
  • const auto&,或者比如const int&会把变量转成const int&的类型,所以不能进一步foo(var)处理这个值
void foo(int& j); //报错,得改成void foo(const int& j);
   int main(){
        int i = 1;
        const int& j = i;
        cout << j << endl;
        foo(j);
        return 0;
}

https://www.youtube.com/watch?v=N1BSWQyHJ3E


这道题还有一个巨坑在中间变量可能超int,所以所有都转成long才行,包括int

最后我的默写:

class Solution {
public:
    int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
        long A_=A, B_=B, C_=C, D_=D, E_=E, F_=F, G_=G, H_=H;
        long cross_area = max((long)0, min(C_,G_)-max(A_,E_))*max((long)0, min(D_,H_)-max(B_,F_));
        int ans = (C_-A_)*(D_-B_) + (G_-E_)*(H_-F_) - cross_area;
        return ans;
    }
};

Runtime: 4 ms, faster than 91.44% of C++ online submissions for Rectangle Area.
Memory Usage: 6.2 MB, less than 73.91% of C++ online submissions for Rectangle Area.


拓展:

836这道题



也就是一行解决:

  • rect1左下角的x必须小于rect2右上角的x (rect1的x_min < rect2的x_max)
  • rect1右上角的x必须大于rect2左下角的x(rect1的x_max > rect2的x_min)
  • rect1左下角的y必须小于rect2右上角的y(rect1的y_min < rect2的y_max)
  • rect1右上角的y必须大于rect2左下角的y(rect1的y_max > rect2的y_min)

其实就是排除了 x y 分别完全在两侧的情况,排除法。


https://www.youtube.com/watch?v=UUjeqglXaSQ

相关文章

网友评论

      本文标题:223. Rectangle Area (M)

      本文链接:https://www.haomeiwen.com/subject/kgwkiktx.html