二维点集的凸包及其直径(1)

前言 :因为前几天做了一个有关凸包的题,并答应crackerwang写个blog解释一下我的算法.因为我比较懒的原因,一直拖到现在才写.预计一共有两篇,第一篇介绍求二维点集凸包的O(N*logN)时间复杂度的算法.第二篇介绍求凸包直径的O(N)时间复杂度的算法.
下面首先给出http://acm.tju.edu.cn/toj/showp2847.html 该题的C++代码,本文将使用Java 代码来描述.
 

cpp 代码
  1. /**  
  2. * TJU 2847 的C++解法  
  3. * Written By Eastsun   
  4. */   
  5. #include<stdio.h>   
  6. #include<math.h>   
  7. #include<algorithm>   
  8. #include<functional>   
  9. #define  S(arr,a,b,c) ((arr[b].x-arr[a].x)*(arr[c].y-arr[a].y)-(arr[c].x-arr[a].x)*(arr[b].y-arr[a].y))    
  10. #define  J(arr,a,b,c,d)  ((arr[b].x-arr[a].x)*(arr[d].y-arr[c].y)-(arr[d].x-arr[c].x)*(arr[b].y-arr[a].y))   
  11. #define  Q(x) ((x)*(x))   
  12. #define  D(arr,a,b) (Q(arr[a].x-arr[b].x)+Q(arr[a].y-arr[b].y))   
  13. using   namespace  std;   
  14.   
  15. struct  Point{   
  16.      double  x,y;   
  17. };   
  18.   
  19. struct  myCmp: public  binary_function<Point,Point, bool >{   
  20.      bool  operator()( const  Point& p1, const  Point& p2) const {   
  21.          if (p1.x==p2.x)  return  p1.y<=p2.y;   
  22.          else             return  p1.x<p2.x;   
  23.     }   
  24. };   
  25.   
  26. int  main(){   
  27.      int  n;   
  28.      while (scanf( "%d" ,&n),n){   
  29.         Point *ps = new  Point[n];   
  30.          for ( int  i=0;i<n;i++) scanf( "%lf%lf" ,&ps[i].x,&ps[i].y);   
  31.         sort(ps,ps+n,myCmp());   
  32.          int  *v = new   int [2*n];   
  33.          int  p,q;   
  34.         p =q =n;   
  35.          for ( int  i=0;i<n;i++){   
  36.             v[p] =v[q] =i;   
  37.              while (p-n>=2&&S(ps,v[p],v[p-1],v[p-2])>=0){v[p-1] =v[p]; p--;}   
  38.              while (n-q>=2&&S(ps,v[q+2],v[q+1],v[q])>=0){v[q+1] =v[q]; q++;}   
  39.             p++;   
  40.             q--;   
  41.         }   
  42.          int  len =p -q -2;   
  43.         Point *pps = new  Point[len+2];   
  44.          for ( int  i=q+1;i<p;i++) pps[i-q] =ps[v[i]];    
  45.         pps[0] =pps[len];   
  46.          int  i=0,j=1;   
  47.          while (J(pps,i,i+1,j,j+1)>0) j++;   
  48.          double  max =0;   
  49.          while (i<=len){   
  50.              double  det =J(pps,i,i+1,j,j+1);   
  51.              if (det<0) i++;   
  52.              else   if (det>0) j =(j+1>len?j+1-len:j+1);   
  53.              else {   
  54.                 i++;   
  55.                  continue ;   
  56.             }   
  57.              double  tmp =D(pps,i,j);   
  58.              if (tmp>max) max =tmp;   
  59.         }   
  60.          delete [] ps;   
  61.          delete [] pps;   
  62.          delete [] v;   
  63.         printf( "%.2lf\n" ,sqrt(max));   
  64.     }   
  65.      return  0;   
  66. }  

一:凸包的定义及其应用
  对于二维点集,其凸包(convex hull)是指包含所有点的最小的凸多边形.直观上看,如果用一条橡皮筋将所有的点圈住,当橡皮筋拉紧后的形状就是这些点的凸包. 下面就是凸包的示意图:

convex hull  

       那么,我们为什么需要凸包这个概念呢?它又能解决什么问题?
       首先,凸包上的点相对原有的点集,我们可以想象,其数量将大大减少.研究表明,对于二维情形,凸包顶点数m(k) =O(n^1/3).更一般的,对于k维球体中均匀分布的n个点,其凸包顶点数m(k) =O(n^(k-1)/(k+1)),可见凸包可大大降低平均意义下的时空复杂度.
      另一方面,凸包相对原有点集增加了一个"序",原来是一个杂乱无章的点集,而现在是一个性质优美的凸多边形,研究起来方便很多.
 
      关于其应用,这里我们只针对TJU2847来说,原题是求一个点集中任意两点的距离的最大值.显然,如果我们直接考虑这个点集中任意两点的距离,时间复杂度是O(N^2),下面我们可以看到,当求出其凸包后,我们可以在O(k)时间内求出这个值(这里的k是指凸包顶点个数k<=N).再加上构造凸包的时间复杂度O(N*logN),我们在O(N*logN)时间复杂度内解决了这个问题.
 
二:构造凸包的算法
      二维点集构造凸包的算法有:卷包裹法(Gift-Wrapping),Graham-Scan扫描法以及分治算法,增量算法等等.这里我采用的是Graham-Scan算法的一种变形--x-y排序.(至于原本的极角排序的Graham-Scan算法,有兴趣的可以参阅《Introduction to Algorithms》第VII章的Computational Geometry一节,里面有详细的说明及正确性证明):
      首先将给定点集对x的值进行排序,x值相同的按y的值排序.简单来说就是从左到右,从下到上排序.
      排序后,记这些点为ps[0,1,..,k],显然点列的第一个点与最后一个点都在凸包上(想一想那个橡皮筋),然后我们从第一点开始到最后一个点进行如下处理:
      构造一个堆栈(数组)stack[],stack[0] =ps[0],然后维持栈中点都是按右手系旋转(或者说从stack[0]到stack[p],所有的点都是按逆时针排列),对于每一个新增加的点,都首先检查栈顶的两个点与其是不是保持右手系,如果是,把这个点加入栈;否则,将栈顶点去掉,继续检查...一直到符合要求为止.

      这样处理后的结果是:stack[]中得到一条连接ps[0]与ps[k]的,并且维持逆时针顺转的链.这个链就是我们要求的凸包的下半部分.用伪代码来描叙就是:

java 代码
  1. //ps中保存了已经排好序的点   
  2. Point[] stack = new  Point[ps.length];   
  3. int  index = 0 , p = 0 ;   
  4. while (index
  5.     stack[p] =ps[index++];   
  6.      while (p>= 2 && stack[p- 2 ],stack[p- 1 ],stack[p] 不是右手系){   
  7.          stack[p- 1 ] =stack[p];   
  8.          p --;   
  9.     }   
  10.     p ++;
  11. }  

      显然,我们再从ps[k]到ps[0]做类似的处理就可以得到凸包的上半部分.当然,事实上我们可以把这两个工作一起做了:维持一个双头栈,使其头部的三个点为右手系,其尾部的三个点为左手系.这样经过一次扫描就可以得到整个凸包.伪代码如下:

java 代码
  1. //ps中保存了已经排好序的点   
  2. Point[] stack = new  Point[ 2 *ps.length];   
  3. int  index = 0 , head =ps.length,tail =ps.length;   
  4. while (index
  5.     stack[head] =stack[tail] =ps[index++];   
  6.      while (head-ps.length>= 2 && stack[head- 2 ],stack[head- 1 ],stack[head] 不是右手系){   
  7.          stack[head- 1 ] =stack[head];   
  8.          head --;   
  9.     }   
  10.      while (ps.length-tail>= 2 && stack[tail+ 2 ],stack[tail+ 1 ],stack[tail] 不是左手系){   
  11.          stack[tail+ 1 ] =stack[tail];   
  12.          tail ++;   
  13.     }   
  14.     head ++;   
  15.     tail --;   
  16. }  

            可以看出,整个算法并不复杂,或者可以说很优美.哦,等等,伪代码里面还有个判断"左手系","右手系"是怎么来的?这就涉及到一个数学概念:叉积

三:叉积
    叉积,又叫外积,向量积.这里我不对叉积做太深入的探讨,只做一些概念性的描叙(且没有考虑数学上的准确性,只是为了解决问题方便),有兴趣的可以找本大学的<解析几何>之类的数学书看看.
    定义:对于二维平面的两个向量a =[xa,ya],b =[xb,yb],其叉积 a×b =xa*yb -xb*ya (其实叉积的定义是在三维空间中的..)
    另一方面,对于点X1 =[x1,y1],X2 =[x2,y2],对应的向量 X1X2 =[x2-x1,y2-y1]
    性质:
    对于平面上的三个点A,B,C所组成的三角形ABC的面积是向量AB与AC叉积的绝对值的一半,即 2*S(A,B,C) =|AB×AC|,并且当A,B,C三点按逆时间顺转时,AB×CD为正;当A,B,C三点按顺时间顺转时,AB×AC为负;A,B,C三点共线时,其叉积为0.

 

四:具体代码
    有了上面的知识,下面给出具体的求凸包的Java代码.
    首先给出用于表示Point的类:

java 代码
  1. package  convex;   
  2. public   class  Point  implements  Comparable<Point>{
  3.      public   double  x,y;   
  4.      public   static   double  distanceSq(Point p1,Point p2){   
  5.          return  (p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y);   
  6.     }   
  7.      public  Point(){   
  8.          this ( 0.0 , 0.0 );   
  9.     }   
  10.      public  Point( double  x, double  y){   
  11.          this .x =x;   
  12.          this .y =y;   
  13.     }   
  14.      /**  
  15.     * 实现Comparable的compareTo方法,将Point按从左到右,从下到上排序  
  16.     */   
  17.      public   int  compareTo(Point p){   
  18.          if (x ==p.x)  return  y==p.y? 0 :(y>p.y? 1 :- 1 );   
  19.          else          return  x>p.x? 1 :- 1 ;   
  20.     }   
  21. }  

 

 下面给出求凸包的代码:
java 代码
  1. package  convex;   
  2. import   static  java.util.Arrays.sort;   
  3. /**  
  4. * 用于求点集凸包以及求凸包直径的算法类  
  5. */   
  6. public   class  Algorithm{   
  7.      //避免生成该类实例   
  8.      private  Algorithm(){}   
  9.      /**  
  10.     * 构造Point数组ps中从fromIndex到toIndex的Point的凸包,时间复杂度O(N*logN)  
  11.     * 注意: 该方法可能改变ps数组中从fromIndex到toIndex元素的顺序  
  12.     * 前置条件: 一个任意的二维点集,不同点的个数>=2  
  13.     *@param ps 保存二维点集的Point数组  
  14.     *@param fromIndex 点集在数组中的起始位置  
  15.     *@param toIndex   点集在数组中的结束位置  
  16.     *@param convex    用来保存凸多边形的顶点的Point数组,其顶点将按逆时针排列  
  17.     *@param offset    保存数据在convex数组中的起始位置  
  18.     *@return length   凸多边形的顶点数目  
  19.     */   
  20.      public   static   int  getPointsConvexClosure(Point[] ps, int  fromIndex, int  toIndex,Point[] convex, int  offset){   
  21.         sort(ps,fromIndex,toIndex);   
  22.          int  len =toIndex -fromIndex;   
  23.         Point[] tmp = new  Point[ 2 *len];   
  24.          int  up =len, down =len;   
  25.          for ( int  index =fromIndex;index
  26.             tmp[up] =tmp[down] =ps[index];   
  27.              while (len-up>= 2 &&multiply(tmp[up+ 2 ],tmp[up+ 1 ],tmp[up])>= 0 ){   
  28.                 tmp[up+ 1 ] =tmp[up];    
  29.                 up++;   
  30.             }   
  31.              while (down-len>= 2 &&multiply(tmp[down- 2 ],tmp[down- 1 ],tmp[down])<= 0 ){   
  32.                 tmp[down- 1 ] =tmp[down];    
  33.                 down--;   
  34.             }   
  35.             up --;   
  36.             down ++;   
  37.         }   
  38.         System.arraycopy(tmp,up+ 1 ,convex,offset,down-up- 2 );   
  39.          return  down-up- 2 ;   
  40.     }   
  41.     /**
        * 计算向量ab与ac的叉积
        */
        private static double multiply(Point a,Point b,Point c){
            return multiply(a,b,a,c);
        }
        /**
        * 计算向量ab与cd的叉积
        */
        private static double multiply(Point a,Point b,Point c,Point d){
            return (b.x-a.x)*(d.y-c.y)-(d.x-c.x)*(b.y-a.y);
        }
  42. }  
凸包的计算(附完整代码)——几何算法 1 平面点集的凸包 1.1 凸包的定义 将平面有限点集 P 的凸包定义为:顶点取自于 P 且包含 P 中所有点的那个唯一的凸多边形(convex polygon)。 正如我们已经定义的,P 的凸包是一个凸多边形。表示多边形的一种自然的方法,就是从任一顶点开始,沿顺时针方向依次列出所有顶点。因此,我们所要求解的问题就变成: 1.2 凸包的简单实现 1.2.1 实现思路及算法 根据凸包的定义,很容易得出,相对于凸包边界上任一边所在的直线,P中所有点均居于同侧。 如下图: 凸包某条边的端点p和q都来自于P;另 阅读详情

相关推荐

PCL 计算点云凹包(2D及3D)(Surface_ConcaveHull)

(5)判断两个外接圆Cpi,Cqi,若其中任意一个外接圆内,不存在点集P中的其他点(即pi及qi处在一个滚球内),那么连接pi及qi,作为凹包的其中一条边。(3)从点集P中任取种子点pi,计算pi同点集P内各点间的距离,并将所有与点pi间距离小于滚球直径alpha * 2的点加入点集Q(初始边界点)。(7)对点集P中所有点,依次进行(3)-(6)步骤,直到所有点被处理。(6)对点集Q中所有点,依次进行(4)(5)步骤,直到所有点被处理。(2)定义一个圆(即滚球),圆半径为alpha。

xhm01291212的博客 2262

二维几何-点集直径

点集直径,即给定点之间的最大距离。两两枚举的方法需要O(n^2)时间,并不是很优秀。 有一个办法可以更快的求出点集的直径。首先求点集的凸包,则最大距离一定来自于凸包上的两个顶点。由于凸包上的点的个数往往比原始点少很多,就算还是两两枚举,速度也比直接枚举快很多,当然最坏情况下时间复杂度仍是O(n^2),需要继续改进。 假设我们已经找到了直径,端点为Pi和Pj,现在我们分别从Pi和Pj出发各作一条...

辣条不爱辣的博客 1582

C#实现滚球算法:从点云提取凹包边界的技术详解与应用

在计算几何与空间数据处理领域,从离散点集提取边界轮廓是一个基础且关键的问题。凸包算法虽能快速生成外轮廓,但无法捕捉地物真实的凹陷特征,限制了其在复杂场景的应用。滚球算法(α-Shape)通过引入一个可调节半径的虚拟圆盘在点集上“滚动”,其核心原理是:若存在一个半径为R的圆盘能经过某两点且内部不含其他点,则这两点间的线段构成边界。这一机制赋予了算法强大的灵活性,通过调整半径参数,可在凸包与精细凹包间平滑过渡,从而精确刻画湖泊、森林、建筑物等不规则实体的真实轮廓。其技术价值在于将严密的几何判定转化为可高效计算的

weixin_34025051的博客 476

平面点集的凸包

概念:给定一个平面的点集q,求覆盖所有点的最小凸多边形(在多边形边上,或内部)。 主要求解思想: 采用分治算法 如图,先找出y坐标最大和做小的点,并入此多边形的顶点集(因为是y坐标最大和最小,所以此直线左边和右边的凸包合起来还是凸包); 对直线左右的点进行递归处理: 如直线左边,先找到一个离直线最远的点p并入多边形顶点集,连接p和ymin和ymax(因为是离直线d最远的点, 所以

bobobe的专栏 7188

轮廓提取之滚球法、凹包算法

滚球法轮廓提取算法。

TxyITxs的博客 3209

【第九期:MATLAB点云处理基础】基于 Alpha Shapes 的边缘点提取

在点云数据处理中,边缘点提取是几何特征识别中的一个基础环节。无论是桥梁截面轮廓提取、预制梁端面孔洞识别,还是建筑物外轮廓重建、构件尺寸测量,都需要先从离散点云中提取能够反映边界形态的点集。对于规则构件而言,边缘点通常对应结构外轮廓、孔洞边界、板件边界或几何突变区域;对于不规则点云而言,边缘点则反映了点云分布的外包络形态。边缘点提取的质量,直接影响后续轮廓拟合、尺寸计算、区域分割和三维重建的精度。本期内容介绍一种基于 Alpha Shapes 思想的点云边缘提取方法,并结合 MATLAB 给出实现流程。

yuchunyu12的博客 203

[凸包] [旋转卡壳]凸包的构建与直径

[凸包][旋转卡壳]凸包的构建与直径 定义 用不严谨的话来讲: 给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点 ——百度百科 严谨的说法是这样的: 在一个实数向量空间\(V\)中,对于给定集合\(X\),所有包含\(X\)的凸集的交集\(S\)被称为\(X\)的凸包。 ——依然是百度百科 比如下面这些点: 它们的凸包长这样: 性质 凸...

weixin_30622181的博客 355

Graham算法求平面散点集的凸包

本文参考自<>章节33.3,利用Graham算法寻找二位平面散点集的凸包,利用OpenGL将计算的结果绘制出来.算法主要利用向量的叉积判断点和线段的位置关系,详见 向量叉积,然后从左下角点按逆时针方向寻找最边缘的线段,利用的原理就是从凸包上任意一点逆时针出发,每到一个节点,一定会向左拐.资源包包含完整的代码实现,部分测试数据和测试结果.

求凸包+旋转卡壳算法——求平面点集S内点对的最远距离

目录 问题:求平面点集S内点对的最远距离... 1 解答:... 1 一.         凸包... 1 二.         旋转卡壳算法... 2 三.         算法总复杂度... 8 四.         C++实现代码... 8 五.         测试... 12   问题:求平面点集S内点对的最远距离 解答:     其实这个问题的解法就是先求这个点集

我和我追逐的梦~~~ 6466

二维快速凸包算法代码(C++)

C++写的二维快速凸包算法,用opengl做了展示,内含详细代码注释

根据已知顶点求构成凸包的顶点集合

根据已知顶点集合,求包含所有点的凸包,代码用java实现,已亲测有效,用的是扫描法,该代码针对二维空间中点。

凹包求解之滚球法

滚球法的思想最初源自于从二维点集重建平面形状的问题,后来笔者将这个思想用于做平面曲线的简化。 例如,下面的平面点集,如何构建其分布区域表示的大致轮廓形状呢? 算法思路的来源-Graham扫描 笔者最初想到的一个从求凸包的GrahamScan算法衍生出来的一个方法。求凸包的GrahamScan算法先找到一个Y最低的点作为起始点,然后使用叉积角度判断的方法去判断点的走向,最后在栈内留下了凸包的点序列。具体的算法讲解与代码,网上一搜各种有,这里就不详细表述。本文要介绍的方法也是和Gra...

大鹏的blog 1万+

计算几何求凸包算法的java实现

计算几何求凸包的java代码,运行可用,可以鼠标任意点击去点,并绘制离散点的最大凸包。

Graham Scan算法:C++实现最小凸包与计算几何实践

在计算几何中,凸包是包裹点集的最小凸多边形,是图形学、碰撞检测和路径规划等领域的核心基础。其原理是通过极角排序和栈维护,剔除凹陷点以保留最外侧轮廓。Graham Scan算法以O(n log n)时间复杂度高效求解,技术价值在于避免了浮点数精度误差,通过向量叉积实现稳健的转向判断。应用场景广泛,如游戏开发中的单位包围圈计算和地理信息系统中的轮廓提取。本文以C++实现为例,深入解析了算法细节,包括极角排序、栈操作和边界处理,并探讨了动态凸包等变体,为工程实践提供了可靠参考。

weixin_30338497的博客 306

平面点集凸包的最优实时算法

上海交通大学建筑工程与力学学王志强等的学术论文,在星形多边形性质的基础之上, 根据凸多边形是特殊的星形多边形, 以星点为中心, 以分别 平行于轴和轴的直线作为相对坐标系的坐标轴, 将平面区域划分为四个区, 依据新的点与有向线 段之间关系的判别式, 从而简便快速地分离内部点和外部点, 对外部点快速找到支撑点, 提出了平面 点集的最优实时算法, 其时间复杂度为它同样适用于多边形并具有相同的时间复杂度它还便 于控制结果凸包的方向, 只需调整初始三角形的方向即可, 算法其它部分无需修改算法具有高效、稳 定等特点, 从而在结合崔国华等的理论基础之上为找到一种线性的排序算法提供了实际的可能性在 文中的结论部分提供了本文算法和经典的算法及堆式排序算法的执行时间的比较

告别迷茫!新手如何从RTKLIB命令行程序入手,快速理解GNSS解算全流程

本文为GNSS新手提供RTKLIB命令行程序实战指南,重点介绍如何通过`rnx2rtkp`后处理解算工具快速掌握GNSS解算全流程。从环境搭建、程序编译到核心算法解析,帮助读者理解RTKLIB源码结构,并通过真实数据处理案例演示完整解算过程,是入门GNSS定位技术的实用教程。

weixin_42524226的博客 359

poj 3608 两凸包最近点,旋转卡壳

http://poj.org/problem?id=3608 给定两个非连接(比如不相交)的凸多边形 P 和 Q, 目标是找到拥有最小距离的点对 (p,q) (p 属于 P 且 q 属于 Q)。 事实上, 多边形非连接十分重要, 因为我们所说的多边形包含其内部。 如果多边形相交, 那么最小距离就变得没有意义了。 然而, 这个问题的另一个版本, 凸多边形顶点对间最小距离对于相交和非相交...

dinglangwei5539的博客 143

uni-app一键登录实战:从云函数配置到前端调用的完整指南

本文详细介绍了uni-app中一键登录功能的实现方法,从DCloud控制台配置到云函数开发,再到前端调用全流程。通过一键登录,用户无需输入账号密码即可快速使用本机手机号登录,显著提升用户体验和登录转化率。文章还提供了常见问题排查和安全合规要点,帮助开发者高效完成集成。

weixin_29291573的博客 446

计算几何刷题计划(转)

刷题时意外找到了一个好题单,记录一下 POJ 1031Fence 计算视角,要注意角度覆盖大于2*PI的情况POJ 1039Pipe 用叉积判断方向的经典题。枚举两凸点,先计算过这两点能否出左口,若可以再计算最右能到到多远。POJ 1066Treasure Hunt 正方形区域中有n条线段,求从边界到某点最少穿过几条线段。黑书练习题。可BFS,还有更简洁的方法。POJ 1070...

461

【分子指纹】化学分子指纹的概念和应用(非常重要)

分子指纹(Molecular fingerprints)可以低计算成本的方式表示大规模化学数据集中化合物的化学(结构、物理化学等)性质。它们在将化学数据集中的分子转换为适合于计算方法的一致输入格式(bit向量或数值)方面发挥着重要作用。在这篇综述中,

DJJ5210的博客 1万+

你的Wi-Fi总断网?可能是DHCP租约到期惹的祸!手把手教你用Windows/路由器设置永久IP或延长租期

本文深入解析家庭Wi-Fi频繁断网的常见原因——DHCP租约到期问题,并提供Windows和路由器设置永久IP或延长租期的详细教程。通过对比静态IP配置与延长租期两种方案,帮助用户有效解决网络不稳定问题,特别适合游戏玩家和远程工作者优化家庭网络环境。

weixin_29305313的博客 1439

AK F.*ing leetcode 流浪计划之delaunay三角化

delaunay 三角化原理及应用

闪电彬彬的博客 367

使用DrissionPage和自动化技术实现得物鞋子信息爬取

本文介绍了一个基于DrissionPage技术的得物鞋子信息采集系统,能自动化采集商品图片、价格等数据并保存为Excel。系统采用浏览器模拟技术处理动态加载内容,通过XPath定位元素,实现智能交互和完整数据采集。关键技术包括:图片URL提取与下载、Excel数据集成与图片嵌入、文件名安全处理等。项目适用于市场分析和学术研究,强调必须遵守法律法规和平台规则,仅用于非商业用途。与API爬虫相比,浏览器自动化能更好处理现代Web应用,但需注意知识产权保护。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 1667
上一篇: 使用CookieHandler管理Cookie数据
下一篇: 一个关于字符串操作的算法题
JavaSxy
博客等级 码龄21年 1粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值