[Leetcode 963] 最小面积矩形 II

题意:

平面坐标系中一些点,找四个拼成面积在最小的矩形。

思路:

长方形判定定理:对角线相等,且互相平分的四边形是矩形。

首先平方枚举两个点所构成的所有线段。

对于这些线段把它们当做长方形的一条对角线,确定了这条对角线之后。

枚举第三个点,首先判断第三个点到对角线中点的距离是不是满足对角线长度的一半,(比较距离)

然后判断,与这三个点构成矩形的第四个点是不是存在:讲解一 

如果以上两个判断都成立,那么算该长方形的面积(四个点都有了,算出长宽之积就ok)

然后用一个全局变量存满足条件的矩形的最小值就好。

讲解一:

如果判断第四个点存不存在呢?假设p1,p2,p3是已知的三个点。p1,p2构成对角线,对角线的中点是(a,b)

那么第四个点的坐标为:p3.x + (p3.x - a),p3.y + (p3.y - b).其中p3.x-a是p3到中点X轴方向的L1距离,仔细体会一下~

然后用一个map存一下所有的点就可以判断这个点在不在集合内了。 

代码:

#define P pair<double,double>
class Solution {
public:
    double esp = 1e-7;
    double clac_len(vector<double>p1,vector<double>p2){  //计算两点之间距离
        double aa = pow(p1[0]-p2[0],2)+pow(p1[1]-p2[1],2);
        return sqrt(aa);
    }
    
    vector<double> to_vector(vector<vector<int>>& points,int num){
        vector<double>tmp;
        tmp.push_back(points[num][0]);tmp.push_back(points[num][1]);
        return tmp;
    }
    
    double minAreaFreeRect(vector<vector<int>>& points) {
        int sz = points.size();
        double ans = 1e15;
        map<P,int>ma;
        for(int i=0;i<sz;i++){
            ma[P(double(points[i][0]),double(points[i][1]))] = 1;
        }
        
        for(int i=0;i<sz;i++){
            for(int j=0;j<sz;j++){
                if(j==i)continue;
                double halfx = (points[i][0]+points[j][0])*1.0/2;  //中点
                double halfy = (points[i][1]+points[j][1])*1.0/2;
                vector<double>half;half.push_back(halfx);half.push_back(halfy);
                for(int a=0;a<sz;a++){
                    if(a==j||a==i)continue;
                    vector<double>tmp1 = to_vector(points,i),tmp2 = to_vector(points,a);
                    if(fabs(clac_len(half,tmp1)-clac_len(half,tmp2))<esp){   //判断第三个点到中点的距离是不是对角线的一半
                        double x = 2*half[0] - points[a][0],y = 2*half[1]-points[a][1]; //计算第四个点
                        if(ma[P(x,y)]==1){
                            vector<double>tmp1 = to_vector(points,i),tmp2 = to_vector(points,a),tmp3 = to_vector(points,j);
                            double chang = clac_len(tmp1,tmp2);
                            double kuan = clac_len(tmp2,tmp3);
                            ans = min(ans,chang*kuan);
                        }
                    }
                }
            }
        }
        if(ans==1e15)ans = 0;
        return ans;
    }
};

此外还有一种平方log的做法.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值