zoukankan      html  css  js  c++  java
  • 凸包模板

    /*
    凸包:
    1.选取最左下边的点p0
    2.根据剩余的m点集Q相对p0的极角排序,如果极角相同,只考虑最远的点
    3.对堆栈进行初始化
    	push(p0,S)
    	push(p1,S)
    	push(p2,S)
    	for i=3 to m 
    		do the angle formed by points next_to_top(s) top(s) and pi make a 
    		nonleft turn
    			do pop(S)
    	    PUSH(pi,S)
    	return S
    */ 
    
    /*
    struct point
    {  double x,y;
    };
    bool mult(point p0,point p1,point p2)
    {   return (p1.x-p0.x)*(p2.y-p0.y)>=(p2.x-p0.x)*(p1.y-p0.y);
    }
    bool operator<(const point &p1,const point &p2)
    {  return p1.y<p2.y||(p1.y==p2.y&&p1.x<p2.x);
    }
    int graham(point pnt[],int n,point res[])//pnt是图中的所有的点,res是通过判断后在凸边行边上的点,
    //而且这些点都是按逆时针存储的,n是所有点的个数。
    {  int i,len,k=0,top=1;
       sort(pnt, pnt + n);
       if(n==0) return 0; res[0]=pnt[0];
       if(n==1) return 1; res[1]=pnt[1];
       if(n==2) return 2; res[2]=pnt[2];
       for(i=2;i<n;i++)
       {  while(top&&mult(pnt[i],res[top],res[top-1]))
            top--;
          res[++top]=pnt[i];
       }
       len=top;res[++top]=pnt[n-2];
       for(i=n-3;i>=0;i--)
       {  while(top!=len&&mult(pnt[i],res[top],res[top-1]))
            top--;
          res[++top]=pnt[i];
       }
       return top; // 返回凸包中点的个数
    }
    
    
    例题1:nyist 圈水池(求凸包中的每个顶点-凸包的简单应用)
    描述
           有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变)
    输入 
          第一行输入的是N,代表用N组测试数据(1<=N<=10),第二行输入的是m,代表本组测试数据共有m个供水装置(3<=m<=100)接下来m行代表的是各个供水装置的横纵坐标
    输出 
         输出各个篱笆经过各个供水装置的坐标点,并且按照x轴坐标值从小到大输出,如果x轴坐标值相同,再安照y轴坐标值从小到大输出
    样例输入
    1
    4
    0 0
    1 1
    2 3
    3 0
    样例输出
    0 0
    2 3
    3 0
    code:
    */
    
    
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    const double EPS = 1E-6;
    
    struct point
    {   
    	int x,y;
    };
    point p[105],res[105];
    double Dist(const point &arg1, const point &arg2)
    {
     	return sqrt( (arg1.x - arg2.x)*(arg1.x - arg2.x) + (arg1.y - arg2.y)*(arg1.y - arg2.y) );
    }
    bool multi(point p0,point p1,point p2)
    {   
    	return (p1.x-p0.x)*(p2.y-p0.y)>(p2.x-p0.x)*(p1.y-p0.y);
    }
    int mysort1(point a,point b)
    {   if(a.y!=b.y) return a.y<b.y;
        if(a.y==b.y&&a.x!=b.x) return a.x<b.x;
    }
    bool cmp(const point &a,const point &b)
    {
    	point temp=p[0];
    	double xmt=(a.x-temp.x)*(b.y-temp.y)-(b.x-temp.x)*(a.y-temp.y);
    	if(xmt)                             //向量不共线就按逆时针旋转
    		return xmt>0;
    	return Dist(a,temp)>Dist(b,temp);//向量共线取最长的。
    }
    
    int main()
    {   int n,k,len;
        cin>>k;
        
        while(k--)
        { 
    	  cin>>n;
          for(int i=0;i<n;i++)
             cin>>p[i].x>>p[i].y;
          sort(p,p+n,mysort1);//排序,找到最左下角的点 
    	   
          res[0]=p[0];
    
          sort(p+1,p+n,cmp);//按照极角排序 
          res[1]=p[1];
          res[2]=p[2];
          int top=2;
          for(int i=3;i<n;i++)
          {  
    			while(multi(p[i],res[top],res[top-1])) 
    				top--;
    			res[++top]=p[i];
          } 
          
    	  for(int i=0;i<=top;i++)
             cout<<res[i].x<<" "<<res[i].y<<endl;
        } 
        
        system("pause");
        return 0;
    }
    
  • 相关阅读:
    ExcelHelper
    c# 文件的读写
    Wav文件操作类
    c# & (与) 、^ (异或)和 >>(<<位移运算)
    c# 高精度的timer
    c# 生成txt文件,写入内容
    C# 对 list<T>中的数据按某字段的大小进行排序
    OC 底层探索 06、 isa 2个经典问题分析
    OC 底层探索 05、属性、成员、实例变量简析
    数据结构与算法 0、 汇总简介
  • 原文地址:https://www.cnblogs.com/zhanglanyun/p/2522473.html
Copyright © 2011-2022 走看看