1. 程式人生 > >LeeCode 587. Erect the Fence

LeeCode 587. Erect the Fence

求凸包。
但是這題有個問題就是需要把在邊界上的點也求出來,那麼在判斷cross的時候應該是<0 而不是 <=0。
還有一個問題是,排序的時候當極角相同的時候,按x從小到大的順序排列的,那麼最後幾個共線的點順序應該倒過來,不然結果只包含一個點。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
using namespace std; struct Point { int x; int y; Point() : x(0), y(0) {} Point(int a, int b) : x(a), y(b) {} }; Point p0; bool cmp(Point &a, Point &b) { if ((a.x - p0.x) * ( b.y - p0.y) - ( a.y - p0.y) * ( b.x - p0.x) != 0) { return (a.x - p0.x) * (b.y - p0.y) - (a.y - p0.y) * (b.x - p0.x) > 0
; } else if (a.x != b.x){ return a.x < b.x; } else { return a.y < b.y; } } int cross(Point a, Point b, Point c) { return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x); } void display(vector<Point> ans) { cout << "---" << endl; for
(int i = 0; i < ans.size(); i++) { cout << ans[i].x << " " << ans[i].y << endl; } cout << "---" << endl; } class Solution { public: vector<Point> outerTrees(vector<Point>& points) { if (points.size() < 2) { return points; } Point p(1e10, 1e10); int min_index = 0; for (int i = 0; i < points.size(); i++) { if ((points[i].x <= p.x && points[i].y <= p.y) || points[i].x < p.x) { min_index = i; p = points[i]; } } p0 = p; swap(points[0], points[min_index]); sort(points.begin() + 1, points.end(), cmp); int len = points.size(); if (cross(points[1], points[len - 1], points[0]) != 0) { int temp = len - 2; while (cross(points[len - 1], points[temp], points[0]) == 0) { temp--; } reverse(points.begin() + temp + 1, points.end()); } // display(points); vector<Point> ans; ans.push_back(points[0]); ans.push_back(points[1]); for (int i = 2; i < points.size(); i++) { int t = ans.size(); while (ans.size() > 1 && cross(ans[t - 1], points[i], ans[t - 2]) < 0) { ans.pop_back(); t = ans.size(); } ans.push_back(points[i]); } return ans; } }; int main() { Solution a; vector<Point> points = {{3, 0}, {4, 0}, {5, 0}, {6, 1}, {7, 2}, {7, 3}, {7, 4}, {6, 5}, {5, 5}, {4, 5}, {3, 5}, {2, 5}, {1, 4}, {1, 3}, {1, 2}, {2, 1}}; vector<Point> ans = a.outerTrees(points); for (int i = 0; i < ans.size(); i++) { cout << ans[i].x << " " << ans[i].y << endl; } return 0; } /* {{1, 1}, {2, 2}, {2, 0}, {2, 4}, {3, 3}, {4, 2}} {{3, 0}, {4, 0}, {5, 0}, {6, 1}, {7, 2}, {7, 3}, {7, 4}, {6, 5}, {5, 5}, {4, 5}, {3, 5}, {2, 5}, {1, 4}, {1, 3}, {1, 2}, {2, 1}, {4, 2}, {0, 3}} */