关于凸包:grahman scan

二维凸包问题(其实还有三维的,但是这里不做研究)是一类关于一个平面上有n个点,让你连接最少的点使给出的所有点在被划定的区域里。如图1: Figure1,这就是一个最优的解。
下面我们开始介绍求解方法之一:graham   scan、。
          首先我们得知道两个有相同起点的矢量(假设p1-->p2,     p1-->p3)的叉积的正负(叉积公式:(p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y))可以代表矢量一是在矢量二的顺时针或逆时针方向。那么根据这个性质,我们可以先从上图取三个点:BG E   B-->G,E-->G调整成B-->G时我们只需要判断一下这两个矢量:B-->E    E-->G的叉积就行了
          理解了这些我们就可以开始接下来的讨论了我们可以对于每一个顶点进行比较,然后得出结论。当然我们可以确定处在最左下的点一定会被取到。那我们把这个当作起点,一个点一个点向外扩张。当然扩张前我们需要对其他点对于以起点为原点x轴的角度先排序,这样就可以保证每一次我们取得点是有序的。
        代码如下:

    #include
#include 
using namespace std;

struct p {
  int x,y;
};
p point [1001];
int n;
p beginn;

int rnd(p beginn,p x,p y)
  {
  return(x.x-beginn.x)*(y.y-beginn.y)-(y.x-beginn.x)*(x.y-beginn.y);
  }

void kp(int x,int y)
{
int i,j;
p k,l;
i=x;j=y;k=point[(x+y)/2];
while(i<=j)
  {
  while(rnd(beginn,point[i],k)<0)i++;
  while(rnd(beginn,point[j],k)>0)j--;
  if(i<=j)
  {
  l=point[i];point[i]=point[j];point[j]=l;
  i++;j--;
  }
 
  }
if(i
  if(j>x)kp(x,j);
}

p line[10001];
int main()
{
int i,j=1,k;
scanf("%d",&n);
for(i=1;i<=n;i++)
  {
  scanf("%d%d",&point[i].x,&point[i].y);
      if(point[j].x>point[i].x||(point[j].x==point[i].x&&point[j].y>point[i].y))
              j=i;
  }
  beginn=point[j];
  point[j]=point[n];
  kp(1,--n);
 
 
  line[1]=beginn;
  line[2]=point[1];
  line[3]=point[2];
  int tail=3;
  for(i=3;i<=n;i++) 
          {
          if(tail<3)
            line[++tail]=point[i];
          else  
            {
              while(rnd(line[tail-1],line[tail],point[i])>=0&&tail!=0)
                tail--;
              line[++tail]=point[i];
                   
}
}
 
printf("%d\n",tail);
for(i=1;i<=tail;i++)
  printf("%d:%d%d\n",i,line[i].x,line[i].y);
}


由于本人只用了几个数据来验证代码正确性,所以代码可能有点问题,欢迎各路大神来指点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值