leecode 解题总结:223. Rectangle Area

本文介绍了一个C++程序,用于计算二维平面上两个矩形相交的面积,并给出了完整的代码实现及特殊情况处理方法。
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
/*
问题:
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.
Rectangle Area
Assume that the total area is never beyond the maximum possible value of int.

分析:求两个矩阵相交的矩阵面积,每个矩阵通过:左下角和右上角的结点确定
可以根据左右,上下矩形的直线方程来做。
求出:矩形A:上下直线方程分别为l1:y=b1,l2: y=b2,求出矩形B的上下直线方程分别为l3:y=b3,l4,y=b4。
且有:b1 > b2, b3 > b4:
1】 b1 > b3
  1.1】 b3 > b2
     1.1.1】 b4 > b2,取: 宽度=b3-b4
	 1.1.2】 b4 <= b2, 取宽度=b3 - b2
	 综上: 宽度=b3 - max(b2 , b4)
  1.2】 b3 <= b2,宽度=0
2】 b1 <= b3
  2.1】b1 > b4,宽度=b1 - max(b2 , b4)
  2.2】b1 <== b4 ,宽度=0
然后:因为水平,所以指向方程类似y=b

同理求取高度:设第一个矩形右边方程:x=b1,左边x=b2
                 二               x=b3,     x=b4
总的面积=宽度* 高度

输入:
-3 0 3 4 0 -1 9 2
0 0 0 0 -1 -1 1 1
0 0 0 0 1 1 2 2 
0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1
输出:
6
4
1

考虑如果其中一个矩形变成一个点:
1】点在另一个矩形中:则面积为另一个面积
2】点不在矩形中:则面积为0
考虑到如果两个矩形都变成点:都为0
1】两点相同,面积为0,点没有面积
2】两点不同,面积为0
考虑到如果其中一个变成线段:
1】线段在另一个矩形中,面积为另一个面积
2】线段不在另一个矩形中,面积为0
考虑到两个矩形都变成线段:面积为0
报错:
Input:
0
0
0
0
-1
-1
1
1
Output:
0
Expected:
4

-2
-2
2
2
3
3
4
4
当出现某个矩阵不存在,左下角和右上角为同一个点,面积为另一个矩形的面积

关键:
1 题目意思都弄错了,不是求相交面积,而是求总的面积。
总面积=两个矩形面积-相交面积
相交面积=( min(C, G) - max(A , E) ) * ( min(H , D) - max(B,F) )
*/

class Solution {
public:
	int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
		int area1 = (C - A) * (D - B);
		int area2 = (G - E) * (H - F);
		//要判断完全重合
		int sumArea = area1 + area2;
		//注意等号
		if(C <= E || G <= A || D <= F || H <= B)
		{
			return sumArea;
		}
		int area = ( min(C, G) - max(A , E) ) * ( min(H , D) - max(B,F) );
		return (sumArea - area);//减去重合的面积
	}
};

void print(vector<int>& result)
{
	if(result.empty())
	{
		cout << "no result" << endl;
		return;
	}
	int size = result.size();
	for(int i = 0 ; i < size ; i++)
	{
		cout << result.at(i) << " " ;
	}
	cout << endl;
}

void process()
{
	 Solution solution;
	 int left1;
	 int left2;
	 int right1;
	 int right2;
	 int top1;
	 int top2;
	 int bottom1;
	 int bottom2;
	 while(cin >> left1 >> bottom1 >> right1 >> top1 >> 
		 left2 >> bottom2 >> right2 >> top2 )
	 {
		 int result = solution.computeArea(left1 , bottom1 , right1 , 
			 top1 , left2 , bottom2 , right2 , top2); 
		 cout << result << endl;
	 }
}

int main(int argc , char* argv[])
{
	process();
	getchar();
	return 0;
}

/*
1】 b1 > b3
  1.1】 b3 > b2
     1.1.1】 b4 > b2,取: 宽度=b3-b4
	 1.1.2】 b4 <= b2, 取宽度=b3 - b2
	 综上: 宽度=b3 - max(b2 , b4)
  1.2】 b3 <= b2,宽度=0
2】 b1 <= b3
  2.1】b1 > b4,宽度=b1 - max(b2 , b4)
  2.2】b1 <== b4 ,宽度=0
	int compute(int aMax , int aMin , int bMax , int bMin)
	{
		if(aMax > bMax)
		{
			if(bMax > aMin)
			{
				return (bMax - max(aMin , bMin));
			}
			else
			{
				return 0;
			}
		}
		else
		{
			if(aMax > bMin)
			{
				return (aMax - max(aMin ,bMin));
			}
			else
			{
				return 0;
			}
		}
	}

	class Result
	{
		Result():_isValid(true){}
		Result(bool isValid , int area):_isValid(isValid),_area(area){}
		bool _isValid;
		int _area;
	};

	//判定至少一个矩形变成0的时候,计算面积,如果bool为true,说明当前是特殊情况,直接用后面计算的值;否则用
	//正常情况处理
	pair<bool , int> checkSpecial(int A, int B, int C, int D, int E, int F, int G, int H)
	{
		//两个都变成点
		if(( A == B && B == C && C == D) && (E == F && F == G && G == H) )
		{
			return pair<bool , int>(true , 0);
		}
		//其中一个变成点,需要检测另一个点是否在矩形中;在矩形中,返回0
		if(A == B && B == C && C == D)
		{
			if(E <= A && F <= A && A <= G && A <= H  )
			{
				return pair<bool ,int>(true , (G - E) * (H - F) );
			}
			else
			{
				return pair<bool , int>(true , 0);
			}
		}

		//判断是否两个都变成横线,如果矩形A变成横线,两个y相同,B=D
		if( B == D)
		{
			//另一个是点,或者横线,面积必定为0
			if(E == F && F == G && G == H)
			{
				return pair<bool , int>(true , 0);
			}
			else if(E == G || F == H )
			{
				return pair<bool , int>(true , 0);
			}
			else
			{
				//直线在矩形中,返回另一个矩形的面积
				if(F <= B && B <= H)
				{
					return pair<bool ,int>(true , (G - E) * (H - F) );
				}
				else
				{
					return pair<bool , int>(true , 0);
				}
			}
		}

		//如果变成竖线
		if( A == C )
		{
			//另一个是点,或者横线,面积必定为0
			if(E == F && F == G && G == H)
			{
				return pair<bool , int>(true , 0);
			}
			else if(E == G || F == H )
			{
				return pair<bool , int>(true , 0);
			}
			else
			{
				//直线在矩形中,返回另一个矩形的面积
				if(E <= A && A <= G)
				{
					return pair<bool ,int>(true , (G - E) * (H - F) );
				}
				else
				{
					return pair<bool , int>(true , 0);
				}
			}
		}

		return pair<bool , int>(false , 0);
	}
	
	//第一个矩形:左下角(A,B),右上角:(C,D),高度: aMax = D;aMin = B;bMax = H ; bMin = F;
	//                                     宽度: aMax = C;aMin = A;bMax = G ; bMin = E;
    int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
        int aMax ;
		int aMin;
		int bMax;
		int bMin;
		int height;
		int width;
		//一种特殊情况,如果ABCD都相同,或者EFGH都相同,面积为
		pair<bool , int> leftCheck = checkSpecial(A , B , C ,D ,E ,F , G , H);
		if(leftCheck.first)
		{
			return leftCheck.second;
		}
		pair<bool , int> rightCheck = checkSpecial(E ,F , G , H , A , B , C ,D);
		if(rightCheck.first)
		{
			return rightCheck.second;
		}
		aMax = D;aMin = B;bMax = H ; bMin = F;
		height = compute(aMax , aMin , bMax , bMin);
		if(0 == height)
		{
			return 0;
		}
		aMax = C;aMin = A;bMax = G ; bMin = E;
		width = compute(aMax , aMin , bMax , bMin);
		return (width * height);
    }
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值