• 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算法是怎么写的!

  • 相关阅读:
    有关Python Selenium的使用心得
    win11 资源管理器右键菜单改回老样式
    js关闭被打开的iframe页面,并在新窗口打开
    sqlplus文件查看oracle自带命令的执行过程
    xtrabackup+MySQL8全备+增备脚本
    DG:有多个备库如何切换
    MySQL匿名空用户名处理
    xtrabackup: error: xb_load_tablespaces() failed with error code 57
    四月常用工具汇总
    yum安装openldap,slapd.conf文件
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330937.html
Copyright © 2020-2023  润新知