1. 程式人生 > >[Leetcode 963] 最小面積矩形 II

[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的做法.