zoukankan      html  css  js  c++  java
  • Andrew算法(我确实不懂Graham)

    先解释一下:这两个算法分别都是凸包问题的算法,然后Andrew是Graham的变种,速度更快,更稳定,非常优秀,介于我已经把Graham写的莫名其妙的WA了,所以我选择了这种算法!

    我认为在这里,还是有必要向大家在这里先普及一下什么是凸包:


    计算几何凸包

    凸包:给你n个散落的点,让你求出最小的凸多边形将所有的点包括起来,或者点在边上。用到的算法是Graham或Andrew!

    这里给一个链接:
    Graham算法详解

    下面给出Andrew算法的思路

    First

    首先先按照x坐标大小或y坐标大小进行排序(如果x坐标一样,y坐标就从小到大排序如果y坐标一样那么x坐标就从小到大排序)

    Second

    然后进入程序的主干部分,先说一下Andrew主干的大体思路,我们分两次来求这个凸包,先从左到右一遍,再从右到左一遍(或先从下到上一遍,再从上到下一遍)首先我们一定要明白第n-1个点一定会在第一遍时进入凸包栈内(看了上面链接的朋友都应该知道这个栈是如何操作的,这里不再赘述)(因为n个点是从0n-1),所以第二遍的时候不必从n-1开始,从n-20开始就可以了(代码上会有体现)然后就完了!

    现在我们来详细讲一下如何实现Second的操作

    我们要实现找凸包,那么就必须找到最外层的点,这里就要使用叉积进行判断(向量a叉向量b=a.x×b.y-b.x×a.y)如果为正a在b的右边反之在左边(题目中因为我们只能定义一个基准坐标系,所以为了实现这个功能我们就必须找参照点,参照点作为临时原点)代码中xmult会体现。

    然后就差不多了!

    下面就是代码了:

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    struct point{
    	int x,y;
    };
    bool cmp(point a,point b)
    {
    	if(a.y==b.y&&a.x<b.x)
    	return true;
    	else if(a.y<b.y) return true;
    	return false;
    }
    double dis(point a,point b)
    {
    	return sqrt((a.x-b.x)*(a.x-b.x)+(b.y-a.y)*(b.y-a.y));
    }
    bool xcross(point a,point b,point c)
    {
    	return (a.x-c.x)*(b.y-c.y)>=(b.x-c.x)*(a.y-c.y);
    }
    point node[100005];
    int num[100005];
    int n;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=0;i<n;++i)
    	{
    		scanf("%d%d",&node[i].x,&node[i].y);
    	}
    	sort(node,node+n,cmp);
    	num[0]=0; num[1]=1;
    	int top=1;
    	for(int i=2;i<n;++i)
    	{
    		while(top>1&&xcross(node[i],node[num[top]],node[num[top-1]]))
    		top--;
    		top++;
    		num[top]=i;
    	}
    	int basic=top;
    	for(int i=n-2;i>=0;--i)
    	{
    		while(top>basic&&xcross(node[i],node[num[top]],node[num[top-1]]))
    		top--;
    		top++;
    		num[top]=i;
    	}
    	double s;
    	s=0.0;
    	for(int i=1;i<=top;++i)
    	{
    		s+=dis(node[num[i-1]],node[num[i]]);
    	}
    	printf("%.1lf",s);
    	return 0;
    }
    

    希望以后能够明白它的father——Gramham算法是怎么写的!

  • 相关阅读:
    移除“xmlns”命名空间
    求质数几种算法
    删除重复字符串的算法
    第一章 搭建一个通用的.net core项目框架
    LSJ_NHibernate第四章 MVC
    LSJ_NHibernate第三章 IDAL,DAL,BLL
    LSJ_NHibernate第二章 ManagerPage
    LSJ_NHibernate第一章 NHibernate介绍
    SQL Server2008R无法登录的解决方案(系统文件损坏)1814 18456....不看别后悔,有用请点赞
    lsjORM ----让开发变得更加快捷(二)
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330937.html
Copyright © 2011-2022 走看看