• 凸包模板


    /*
    凸包:
    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;
    }
    
  • 相关阅读:
    OK335xS-Android mkmmc-android-ubifs.sh hacking
    OK335xS-Android pack-ubi-256M.sh hacking
    OK335xS Ubuntu 12.04.1 版本 Android 开发环境搭建
    Qt Quick Hello World hacking
    Qt QML referenceexamples attached Demo hacking
    QT 5.4.1 for Android Ubuntu QtWebView Demo
    I.MX6 working note for high efficiency
    QT 5.4.1 for Android Windows环境搭建
    mkbootimg hacking
    Generate And Play A Tone In Android hacking
  • 原文地址:https://www.cnblogs.com/zhanglanyun/p/2522473.html
Copyright © 2020-2023  润新知