POJ 1113 解题报告

来源:互联网 发布:淘宝网秋冬裙子 编辑:程序博客网 时间:2024/05/22 04:34

为了以后搜索方便,注:这道题是凸包问题。用的是convex hull的扫描算法。

这道题实际上是个convex hull的问题。因为无论有些点凹进去多少,实际上是由那些convex hull上的凸点决定了最短的边界的形状。所以最终的围栏周长是convex hull的周长加上一个完整的园的周长(半径就是L)。

代码用的是我之前的代码:http://blog.csdn.net/thestoryofsnow/article/details/38516855

1113Accepted180K16MSC++2488B

/* ID: thestor1 LANG: C++ TASK: poj1113 */#include <iostream>#include <fstream>#include <cmath>#include <cstdio>#include <cstring>#include <limits>#include <string>#include <vector>#include <list>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>#include <cassert>using namespace std;class Point{public:int x, y;Point(){Point(0, 0);}Point (int x, int y){this->x = x;this->y = y;}bool operator <(const Point &p) const {return x < p.x || (x == p.x && y < p.y);}friend ostream& operator<<(ostream& os, const Point& p);};ostream& operator<<(ostream& os, const Point& p){os << p.x << "\t" << p.y;return os;}int cross(const Point &left, Point &middle, Point &right){return (left.x - middle.x) * (right.y - middle.y) - (right.x - middle.x) * (left.y - middle.y);}int crossProduct(int x1, int y1, int x2, int y2){return x1 * y2 - x2 * y1;}double dis(Point p1, Point p2){return sqrt((double)((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)));}double convexhull(std::vector<Point> &points){sort(points.begin(), points.end());// for (int i = 0; i < points.size(); ++i)// {// cout<<points[i]<<endl;// }std::vector<int> convexhull(2 * points.size());int k = 0;for (int i = 0; i < points.size(); ++i){while (k >= 2 && cross(points[convexhull[k - 2]], points[convexhull[k - 1]], points[i]) <= 0){k--;}convexhull[k] = i;k++;}for (int i = points.size() - 2, t = k + 1; i >= 0; --i){while (k >= t && cross(points[convexhull[k - 2]], points[convexhull[k - 1]], points[i]) <= 0){k--;}convexhull[k] = i;k++;}convexhull.resize(k);// cout<<"convexhull:"<<endl;// for (int i = 0; i < convexhull.size(); ++i)// {// cout<<points[convexhull[i]]<<endl;// }double perimeter = 0.00;for (int i = 0; i < convexhull.size() - 1; ++i){perimeter += dis(points[convexhull[i]], points[convexhull[i + 1]]);}// cout << "perimeter:" << perimeter << endl;return perimeter;}int main(){int N, L;scanf("%d%d", &N, &L);std::vector<Point> points(N);for (int i = 0; i < N; ++i){scanf("%d%d", &points[i].x, &points[i].y);}double perimeter = convexhull(points);double circle = 2 * 3.141592653 * L;printf("%.0f\n", perimeter + circle);return 0;  }


0 0
原创粉丝点击