寻找凸包-graham扫描法
2015-10-24 19:22
316 查看
Graham扫描法通过维持一个关于候选点的栈S来解决凸包问题。输入集合Q中的每个点都被压栈一次,非CH(Q)中的点最终被弹出栈。当算法终止时,栈S仅包含CH(Q)中的顶点,以逆时针的顺序出现在边界上。
<span style="font-size:18px;">import java.util.*; public class Graham { static int MAX = 100015; static POINT[] point = new POINT[MAX]; static int[] stack = new int[MAX]; static int n; static int top; static class POINT { public double x,y; public POINT(int x,int y){ this.x = x; this.y = y; } } //(p1-p0)x(p2-p0),判断两直线的相对位置 static double xmul(POINT p1,POINT p2,POINT p0){ return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y); } static double distance(POINT p1,POINT p2){ return (p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y); } static void swap(int i,int j){ POINT tmp = point[i]; point[i] = point[j]; point[j] = tmp; } static void grahamscan(int n){ // if(n<2) int u = 0,i = 0; for(;i < n;i++) if((point[i].y < point[u].y)||(point[i].y == point[u].y && point[i].x<point[u].x )) u = i; swap(u,0); Arrays.sort(point,0,n,new MyComp()); for(i=0;i<3;i++) stack[i] = i; //point0 point1 point2入栈 top = 2; for(i = 3;i < n;i++){ while(xmul(point[i],point[stack[top]],point[stack[top-1]]) >= 0){//弹出非左转的点 if(top == 0) break; top--; } stack[++top] = i; } } static class MyComp implements Comparator<POINT> { public int compare(POINT p1,POINT p2){ double xm = xmul(p1,p2,point[0]); if(xm < 0) return 1; else if(xm == 0 && distance(p1,point[0])>distance(p2,point[0])) return 1; else return -1; } } static double area(int n){ double area = 0; for(int i = 2;i <= n-1;i++){ area += xmul(point[stack[i]],point[stack[i-1]],point[0]); } return Math.abs(area)/2; } static void input(){ int x=0,y=0; Scanner cin = new Scanner(System.in); System.out.println("请输入点数"); n = cin.nextInt(); System.out.println("请输入x,y"); for(int i = 0;i < n;i++){ x = cin.nextInt(); y = cin.nextInt(); point[i] = new POINT(x,y); } } static void print(){ System.out.println("凸包:"); for(int i=0;i<=top;i++){ System.out.print(stack[i]+"-"); } System.out.println("0"); } public static void main(String[] args){ input(); grahamscan(n); System.out.println("area: "+area(n)); print(); } } /* 请输入点数 4 请输入x,y 0 0 1 0 0 1 1 1 area: 1.0 0-1-2-3-0 */</span>
相关文章推荐
- 心得笔记
- JavaScript描述数据结构与算法——列表
- 推理的勇者,黑化超凡or普通平淡
- CodeForces 534A-A - Exam-构造水题
- mysql 第07章 函数
- 图种的批量制作(jpg+rar隐藏信息)
- Codeforces 9A-Die Roll(意甲冠军)
- [JCWC2005]Draw
- 写一个Windows上的守护进程(1)开篇
- 【PAT】1102. Invert a Binary Tree (25)
- 黑马程序员——————泛型的使用与Map的初步学习
- Java基础(3)----选择与循环语句
- UML之用例图
- Java基础程序设计---数据类型
- [深入理解Java虚拟机]第七章 类加载的过程
- linux下ElasticSearch安装部署
- 2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest A题:Anagrams [打表/规律题]
- 关于javascript中this的理解
- className.class.getResourceAsStream()与ClassLoader.getSystemResourceAsStream() 的区别
- C++对象模型——默认构造函数的合成