日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 587. 安装栅栏 / LintCode 1152. 安装栅栏(凸包检测:排序+叉积正负判断+正反扫描+去重)

發布時間:2024/7/5 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 587. 安装栅栏 / LintCode 1152. 安装栅栏(凸包检测:排序+叉积正负判断+正反扫描+去重) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. 題目
    • 2. 解題

1. 題目

在一個二維的花園中,有一些用 (x, y) 坐標表示的樹。
由于安裝費用十分昂貴,你的任務是先用最短的繩子圍起所有的樹。
只有當所有的樹都被繩子包圍時,花園才能圍好柵欄。
你需要找到正好位于柵欄邊界上的樹的坐標。

示例 1:
輸入: [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]]
輸出: [[1,1],[2,0],[4,2],[3,3],[2,4]]
解釋:

示例 2:
輸入: [[1,2],[2,2],[4,2]]
輸出: [[1,2],[2,2],[4,2]]
解釋:

即使樹都在一條直線上,你也需要先用繩子包圍它們。

注意:
所有的樹應當被圍在一起。你不能剪斷繩子來包圍樹或者把樹分成一組以上。
輸入的整數在 0 到 100 之間。
花園至少有一棵樹。
所有樹的坐標都是不同的。
輸入的點沒有順序。輸出順序也沒有要求。

來源:力扣(LeetCode) 鏈接:https://leetcode-cn.com/problems/erect-the-fence
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。

LintCode 題目地址:https://www.lintcode.com/problem/erect-the-fence/description

2. 解題

  • 將所有的點按 x,y 排序
  • 先將前面兩個點加入答案,正序檢查當前點跟答案里最后兩個點組成的向量的叉積指向是否滿足凸包要求,不滿足,則將答案里最后一個點彈出,滿足,則將點壓入答案。得到下邊界
  • 然后逆序檢查,得到上邊界,然后去重

下圖考慮的是下邊界,正序遍歷的情況

/*** Definition for a point.* struct Point {* int x;* int y;* Point() : x(0), y(0) {}* Point(int a, int b) : x(a), y(b) {}* };*/ // LintCode 輸入格式不太一樣 struct cmp{bool operator()(const Point a, const Point b) const{return a.x<b.x || (a.x==b.x && a.y<b.y);} }; class Solution { public:vector<Point> outerTrees(vector<Point> &points) {// write your code heresort(points.begin(), points.end(),[&](auto &a, auto &b){return a.x < b.x || (a.x == b.x && a.y < b.y);});vector<Point> ans;for(int i = 0; i < points.size(); ++i){while(ans.size()>=2 && dot(ans[ans.size()-2], ans[ans.size()-1],points[i]) < 0)ans.pop_back();ans.push_back(points[i]);}for(int i = points.size()-1; i >= 0; --i){while(ans.size()>=2 && dot(ans[ans.size()-2], ans[ans.size()-1],points[i]) < 0)ans.pop_back();ans.push_back(points[i]);}set<Point, cmp> set(ans.begin(), ans.end());vector<Point> res(set.begin(), set.end());return res;}int dot(Point& a, Point& b, Point& c){int x1 = b.x-a.x;int y1 = b.y-a.y;int x2 = c.x-b.x;int y2 = c.y-b.y;return x1*y2-x2*y1;} }; // LeetCode class Solution { public:vector<vector<int>> outerTrees(vector<vector<int>>& points) {sort(points.begin(), points.end());vector<vector<int>> ans;for(int i = 0; i < points.size(); ++i){while(ans.size()>=2 && dot(ans[ans.size()-2], ans[ans.size()-1],points[i]) < 0)ans.pop_back();ans.push_back(points[i]);}for(int i = points.size()-1; i >= 0; --i){while(ans.size()>=2 && dot(ans[ans.size()-2], ans[ans.size()-1],points[i]) < 0)ans.pop_back();ans.push_back(points[i]);}set<vector<int>> set(ans.begin(), ans.end());vector<vector<int>> res(set.begin(), set.end());return res;}int dot(vector<int>& a, vector<int>& b, vector<int>& c){int x1 = b[0]-a[0];int y1 = b[1]-a[1];int x2 = c[0]-b[0];int y2 = c[1]-b[1];return x1*y2-x2*y1;} }; // 80 ms 22.9 MB C++

我的CSDN博客地址 https://michael.blog.csdn.net/

長按或掃碼關注我的公眾號(Michael阿明),一起加油、一起學習進步!

總結

以上是生活随笔為你收集整理的LeetCode 587. 安装栅栏 / LintCode 1152. 安装栅栏(凸包检测:排序+叉积正负判断+正反扫描+去重)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。