[POJ 3348] Cows 凸包模板
2015-08-02 12:01
459 查看
http://poj.org/problem?id=3348
题意:用树围城一块地, 求最大的面积。
思路:凸包加多边形面积
点集排序(0ms):
极角排序(16ms):
题意:用树围城一块地, 求最大的面积。
思路:凸包加多边形面积
点集排序(0ms):
[code]#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 10015; struct Point{ int x, y; friend bool operator < (Point a, Point b){ return a.y < b.y || (a.y == b.y && a.x < b.x); } }; //叉积 double mult(Point a, Point b, Point c){ return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); } int graham(int n, Point *point, Point *res) { sort(point, point+n); //点集排序 if(n == 0) return 0; res[0] = point[0]; if(n == 1) return 1; res[1] = point[1]; if(n == 2) return 2; res[2] = point[2]; int top = 1; //求半个凸包 for(int i = 2; i < n; i++){ while(top && mult(point[i], res[top], res[top-1]) >= 0){ top--; } res[++top] = point[i]; } //另外半个凸包 int len = top; for(int i = n-2; i >= 0; i--){ while(top > len && mult(point[i], res[top], res[top-1]) >= 0){ top--; } res[++top] = point[i]; } return top; } //多边形面积 double Area(int n, Point *res) { double sum = 0.0; if(n < 3) return sum; for(int i = 0; i < n; i++){ sum += mult(res[0], res[i], res[(i+1)%n]); //叉积求面积 } return sum / 2.0; } Point res[maxn]; Point point[maxn]; int main() { int n; while(~scanf("%d", &n)){ for(int i = 0; i < n; i++){ scanf("%d%d", &point[i].x, &point[i].y); } int top = graham(n, point, res); double sum = Area(top, res) / 50; printf("%d\n",(int)abs(sum)); } return 0; }
极角排序(16ms):
[code]#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 10015; const double eps = 1e-8; struct Point{ double x, y; friend bool operator < (Point a, Point b){ return a.y < b.y || (a.y == b.y && a.x < b.x); } }; Point res[maxn]; Point point[maxn]; //周长 double length(Point a, Point b){ return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y); } //叉积 double mult(Point a, Point b, Point c){ return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); } //求面积 double Area(int n, Point *res) { double sum = 0.0; if(n < 2) return sum; for(int i = 1; i < n; i++){ sum += fabs(mult(res[0], res[i], res[i+1])); //叉积的绝对值就是构成的三角形面积的两倍 } return sum / 2.0; } //极角排序 bool cmp(Point a, Point b) { int k = mult(point[0], a, b); return k > 0 || (k == 0 && length(point[0], a) < length(point[0], b)); } int graham(int n, Point *point, Point *res) { sort(point, point+n, cmp); //极角排序 if(n == 0) return 0; res[0] = point[0]; if(n == 1) return 1; res[1] = point[1]; if(n == 2) return 2; res[2] = point[2]; int top = 1; for(int i = 2; i < n; i++){ while(top && mult(point[i], res[top], res[top-1]) >= 0){ top--; } res[++top] = point[i]; } return top; } int main() { int n; while(~scanf("%d", &n)){ int tx = 100000, ty = 100000, mid; for(int i = 0; i < n; i++){ scanf("%lf%lf", &point[i].x, &point[i].y); if(point[i].y < ty || (point[i].y == ty && point[i].x < tx)){ mid = i; tx = point[i].x; ty = point[i].y; } } point[mid] = point[0]; // 极角排序要求point[0]是最左下角的点 point[0].x = tx, point[0].y = ty; int top = graham(n, point, res); double sum = Area(top, res) / 50; printf("%d\n",(int)sum); } return 0; }
相关文章推荐
- 三大框架面试题
- VC6.0工程转换到VS2010版本的常见问题
- DT大数据梦工厂 第75讲
- Win7版IE10浏览器正式版官方下载地址
- VMWare虚拟机中安装Redhat linux操作系统图解(2)
- poj2367Genealogical tre
- DICOM:dcm4che工具包如何压缩dcm文件探讨(续篇)
- 数据结构基础温故-5.图(下):最短路径
- 第八课,T语言功能和参数(版本5.0)
- (算法)求1到1亿间的质数或素数
- 文章标题
- Linxu命令与文件的搜索 - which, whereis, locate, find
- Linxu命令与文件的搜索 - which, whereis, locate, find
- jQuery
- VMWare虚拟机中安装Redhat linux操作系统图解(1)
- Linux vi中文乱码处理
- JDBC在getConnection之前为什么要调用Class.forName
- oracle函数
- centsOs(Linux) memcache 安装教程
- python 中文乱码解决方法