zoukankan      html  css  js  c++  java
  • 计算几何几何函数库

      1  计算几何几何函数库
      2 -------------------------------------------------------------------------------------------------------------------------------
      3 导引
      4 1. 常量定义和包含文件
      5 2. 基本数据结构
      6 3. 精度控制
      7 ㈠ 点的基本运算
      8 1. 平面上两点之间距离
      9 2. 判断两点是否重合
     10 3. 矢量叉乘
     11 4. 矢量点乘
     12 5. 判断点是否在线段上
     13 6. 求一点饶某点旋转后的坐标
     14 7. 求矢量夹角
     15 ㈡ 线段及直线的基本运算
     16 1. 点与线段的关系
     17 2. 求点到线段所在直线垂线的垂足
     18 3. 点到线段的最近点
     19 4. 点到线段所在直线的距离
     20 5. 点到折线集的最近距离
     21 6. 判断圆是否在多边形内
     22 7. 求矢量夹角余弦
     23 8. 求线段之间的夹角
     24 9. 判断线段是否相交
     25 10.判断线段是否相交但不交在端点处
     26 11.求点关于某直线的对称点
     27 12.判断两条直线是否相交及求直线交点
     28 13.判断线段是否相交,如果相交返回交点
     29 ㈢ 多边形常用算法模块
     30 1. 判断多边形是否简单多边形
     31 2. 检查多边形顶点的凸凹性
     32 3. 判断多边形是否凸多边形
     33 4. 求多边形面积
     34 5. 判断多边形顶点的排列方向
     35 7. 射线法判断点是否在多边形内
     36 8. 判断点是否在凸多边形内
     37 9. 寻找点集的graham算法
     38 10.寻找点集凸包的卷包裹法
     39 11.凸包MelkMan算法的实现
     40 12. 凸多边形的直径
     41 13.求凸多边形的重心
     42 ===========================================================================
     43 导引
     44 /* 需要包含的头文件 */
     45 #include <cmath >
     46 /* 常量定义 */
     47 const double INF = 1E200;
     48 const double EP = 1E-10;
     49 const int MAXV = 300;
     50 const double PI = 3.14159265;
     51 /* 基本几何结构 */
     52 struct POINT
     53 {
     54 double x;
     55 double y;
     56 POINT(double a=0, double b=0) { x=a; y=b;}
     57 };
     58 struct LINESEG
     59 {
     60 POINT s;
     61 POINT e;
     62 LINESEG(POINT a, POINT b) { s=a; e=b;}
     63 LINESEG() { }
     64 };
     65 // 直线的解析方程 a*x+b*y+c=0 为统一表示,约定 a>= 0
     66 struct LINE
     67 {
     68 double a;
     69 double b;
     70 double c;
     71 LINE(double d1=1, double d2=-1, double d3=0) {a=d1; b=d2; c=d3;}
     72 };
     73 //线段树
     74 struct LINETREE
     75 {
     76 }
     77 //浮点误差的处理
     78 int dblcmp(double d)
     79 {
     80 if(fabs(d)<EP)
     81 return 0 ;
     82 return (d>0) ?1 :-1 ;
     83 }
     84 <一>点的基本运算
     85 // 返回两点之间欧氏距离
     86 double dist(POINT p1,POINT p2)
     87 {
     88 return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) );
     89 }
     90 // 判断两个点是否重合
     91 bool equal_point(POINT p1,POINT p2)
     92 {
     93 return ( (abs(p1.x-p2.x)<EP)&&(abs(p1.y-p2.y)<EP) );
     94 }
     95 /*(sp-op)*(ep-op)的叉积
     96 r=multiply(sp,ep,op),得到(sp-op)*(ep-op)的叉积
     97 r>0:sp在矢量op ep的顺时针方向;
     98 r=0:op sp ep三点共线;
     99 r<0: sp在矢量op ep的逆时针方向 */
    100 double multiply(POINT sp,POINT ep,POINT op)
    101 {
    102 return((sp.x-op.x)*(ep.y-op.y) - (ep.x-op.x)*(sp.y-op.y));
    103 }
    104 double amultiply(POINT sp,POINT ep,POINT op)
    105 {
    106 return fabs((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
    107 }
    108 /*矢量(p1-op)和(p2-op)的点积
    109 r=dotmultiply(p1,p2,op),得到矢量(p1-op)和(p2-op)的点积如果两个矢量都非零矢量
    110 r < 0: 两矢量夹角为锐角;
    111 r = 0:两矢量夹角为直角;
    112 r > 0: 两矢量夹角为钝角 */
    113 double dotmultiply(POINT p1,POINT p2,POINT p0)
    114 {
    115 return ((p1.x-p0.x)*(p2.x-p0.x) + (p1.y-p0.y)*(p2.y-p0.y));
    116 }
    117 /* 判断点p是否在线段l上
    118 条件:(p在线段l所在的直线上)&& (点p在以线段l为对角线的矩形内) */
    119 bool online(LINESEG l,POINT p)
    120 {
    121 return ((multiply(l.e,p,l.s)==0)
    122 && ( ( (p.x-l.s.x) * (p.x-l.e.x) <=0 ) && ( (p.y-l.s.y)*(p.y-l.e.y) <=0 ) ) );
    123 }
    124 // 返回点p以点o为圆心逆时针旋转alpha(单位:弧度)后所在的位置
    125 POINT rotate(POINT o,double alpha,POINT p)
    126 {
    127 POINT tp;
    128 p.x -=o.x;
    129 p.y -=o.y;
    130 tp.x=p.x*cos(alpha) - p.y*sin(alpha)+o.x;
    131 tp.y=p.y*cos(alpha) + p.x*sin(alpha)+o.y;
    132 return tp;
    133 }
    134 /* 返回顶角在o点,起始边为os,终止边为oe的夹角(单位:弧度)
    135 角度小于pi,返回正值
    136 角度大于pi,返回负值
    137 可以用于求线段之间的夹角 */
    138 double angle(POINT o,POINT s,POINT e)
    139 {
    140 double cosfi,fi,norm;
    141 double dsx = s.x - o.x;
    142 double dsy = s.y - o.y;
    143 double dex = e.x - o.x;
    144 double dey = e.y - o.y;
    145 cosfi=dsx*dex+dsy*dey;
    146 norm=(dsx*dsx+dey*dey)*(dex*dex+dey*dey);
    147 cosfi /= sqrt( norm );
    148 if (cosfi >= 1.0 ) return 0;
    149 if (cosfi <= -1.0 ) return -3.1415926;
    150 fi=acos(cosfi);
    151 if (dsx*dey-dsy*dex>0) return fi;// 说明矢量os 在矢量 oe的顺时针方向
    152 return -fi;
    153 }
    154 <二>线段及直线的基本运算
    155 /* 判断点C在线段AB所在的直线l上垂足P的与线段AB的关系
    156 本函数是根据下面的公式写的,P是点C到线段AB所在直线的垂足
    157 AC dot AB
    158 r = ----------------------
    159 ||AB||^2
    160 (Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay)
    161 = ----------------------------------------------------
    162 L^2
    163 r has the following meaning:
    164 r=0 P = A
    165 r=1 P = B
    166 r<0 P is on the backward extension of AB
    167 r>1 P is on the forward extension of AB
    168 0<r<1 P is interior to AB
    169 */
    170 double relation(POINT c,LINESEG l)
    171 {
    172 LINESEG tl;
    173 tl.s=l.s;
    174 tl.e=c;
    175 return dotmultiply(tl.e,l.e,l.s)/(dist(l.s,l.e)*dist(l.s,l.e));
    176 }
    177 // 求点C到线段AB所在直线的垂足 P
    178 POINT perpendicular(POINT p,LINESEG l)
    179 {
    180 double r=relation(p,l);
    181 POINT tp;
    182 tp.x=l.s.x+r*(l.e.x-l.s.x);
    183 tp.y=l.s.y+r*(l.e.y-l.s.y);
    184 return tp;
    185 }
    186 /* 求点p到线段l的最短距离
    187 返回线段上距该点最近的点np 注意:np是线段l上到点p最近的点,不一定是垂足 */
    188 double ptolinesegdist(POINT p,LINESEG l,POINT &np)
    189 {
    190 double r=relation(p,l);
    191 if(r<0)
    192 {
    193 np=l.s;
    194 return dist(p,l.s);
    195 }
    196 if(r>1)
    197 {
    198 np=l.e;
    199 return dist(p,l.e);
    200 }
    201 np=perpendicular(p,l);
    202 return dist(p,np);
    203 }
    204 // 求点p到线段l所在直线的距离
    205 //请注意本函数与上个函数的区别
    206 double ptoldist(POINT p,LINESEG l)
    207 {
    208 return abs(multiply(p,l.e,l.s))/dist(l.s,l.e);
    209 }
    210 /* 计算点到折线集的最近距离,并返回最近点.
    211 注意:调用的是ptolineseg()函数 */
    212 double ptopointset(int vcount, POINT pointset[], POINT p, POINT &q)
    213 {
    214 int i;
    215 double cd=double(INF),td;
    216 LINESEG l;
    217 POINT tq,cq;
    218 for(i=0;i<vcount-1;i++)
    219 {
    220 l.s=pointset[i];
    221 l.e=pointset[i+1];
    222 td=ptolinesegdist(p,l,tq);
    223 if(td<cd)
    224 {
    225 cd=td;
    226 cq=tq;
    227 }
    228 }
    229 q=cq;
    230 return cd;
    231 }
    232 /* 判断圆是否在多边形内*/
    233 bool CircleInsidePolygon(int vcount,POINT center,double radius,POINT polygon[])
    234 {
    235 POINT q;
    236 double d;
    237 q.x=0;
    238 q.y=0;
    239 d=ptopointset(vcount,polygon,center,q);
    240 if(d<radius||fabs(d-radius)<EP) return true;
    241 else return false;
    242 }
    243 /* 返回两个矢量l1和l2的夹角的余弦 (-1 ~ 1)
    244 注意:如果想从余弦求夹角的话,注意反余弦函数的值域是从 0到pi */
    245 double cosine(LINESEG l1,LINESEG l2)
    246 {
    247 return(((l1.e.x-l1.s.x)*(l2.e.x-l2.s.x)+(l1.e.y-l1.s.y)*(l2.e.y-l2.s.y))/(dist(l1.e,l1.s)*dist(l2.e,l2.s))) );
    248 }
    249 // 返回线段l1与l2之间的夹角
    250 //单位:弧度 范围(-pi,pi)
    251 double lsangle(LINESEG l1,LINESEG l2)
    252 {
    253 POINT o,s,e;
    254 o.x=o.y=0;
    255 s.x=l1.e.x-l1.s.x;
    256 s.y=l1.e.y-l1.s.y;
    257 e.x=l2.e.x-l2.s.x;
    258 e.y=l2.e.y-l2.s.y;
    259 return angle(o,s,e);
    260 }
    261 //判断线段u和v相交(包括相交在端点处)
    262 bool intersect(LINESEG u,LINESEG v)
    263 {
    264 return ( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&& //排斥实验
    265 (max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&
    266 (max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&
    267 (max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&
    268 (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0)&& //跨立实验
    269 (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));
    270 }
    271 // 判断线段u和v相交(不包括双方的端点)
    272 bool intersect_A(LINESEG u,LINESEG v)
    273 {
    274 return ((intersect(u,v)) &&
    275 (!online(u,v.s)) &&
    276 (!online(u,v.e)) &&
    277 (!online(v,u.e)) &&
    278 (!online(v,u.s)));
    279 }
    280 // 判断线段v所在直线与线段u相交
    281 方法:判断线段u是否跨立线段v
    282 bool intersect_l(LINESEG u,LINESEG v)
    283 {
    284 return multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0;
    285 }
    286 // 根据已知两点坐标,求过这两点的直线解析方程: a*x+b*y+c = 0 (a >= 0)
    287 LINE makeline(POINT p1,POINT p2)
    288 {
    289 LINE tl;
    290 int sign = 1;
    291 tl.a=p2.y-p1.y;
    292 if(tl.a<0)
    293 {
    294 sign = -1;
    295 tl.a=sign*tl.a;
    296 }
    297 tl.b=sign*(p1.x-p2.x);
    298 tl.c=sign*(p1.y*p2.x-p1.x*p2.y);
    299 return tl;
    300 }
    301 // 根据直线解析方程返回直线的斜率k,水平线返回 0,竖直线返回 1e200
    302 double slope(LINE l)
    303 {
    304 if(abs(l.a) < 1e-20)return 0;
    305 if(abs(l.b) < 1e-20)return INF;
    306 return -(l.a/l.b);
    307 }
    308 // 返回直线的倾斜角alpha ( 0 - pi)
    309 // 注意:atan()返回的是 -PI/2 ~ PI/2
    310 double alpha(LINE l)
    311 {
    312 if(abs(l.a)< EP)return 0;
    313 if(abs(l.b)< EP)return PI/2;
    314 double k=slope(l);
    315 if(k>0)
    316 return atan(k);
    317 else
    318 return PI+atan(k);
    319 }
    320 // 求点p关于直线l的对称点
    321 POINT symmetry(LINE l,POINT p)
    322 {
    323 POINT tp;
    324 tp.x=((l.b*l.b-l.a*l.a)*p.x-2*l.a*l.b*p.y-2*l.a*l.c)/(l.a*l.a+l.b*l.b);
    325 tp.y=((l.a*l.a-l.b*l.b)*p.y-2*l.a*l.b*p.x-2*l.b*l.c)/(l.a*l.a+l.b*l.b);
    326 return tp;
    327 }
    328 // 如果两条直线 l1(a1*x+b1*y+c1 = 0), l2(a2*x+b2*y+c2 = 0)相交,返回true,且返回交点p
    329 bool lineintersect(LINE l1,LINE l2,POINT &p) // 是 L1,L2
    330 {
    331 double d=l1.a*l2.b-l2.a*l1.b;
    332 if(abs(d)<EP) // 不相交
    333 return false;
    334 p.x = (l2.c*l1.b-l1.c*l2.b)/d;
    335 p.y = (l2.a*l1.c-l1.a*l2.c)/d;
    336 return true;
    337 }
    338 // 如果线段l1和l2相交,返回true且交点由(inter)返回,否则返回false
    339 bool intersection(LINESEG l1,LINESEG l2,POINT &inter)
    340 {
    341 LINE ll1,ll2;
    342 ll1=makeline(l1.s,l1.e);
    343 ll2=makeline(l2.s,l2.e);
    344 if(lineintersect(ll1,ll2,inter)) return online(l1,inter);
    345 else return false;
    346 }
    347 <三> 多边形常用算法模块
    348 如果无特别说明,输入多边形顶点要求按逆时针排列
    349 // 返回多边形面积(signed);
    350 // 输入顶点按逆时针排列时,返回正值;否则返回负值
    351 double area_of_polygon(int vcount,POINT polygon[])
    352 {
    353 int i;
    354 double s;
    355 if (vcount<3)
    356 return 0;
    357 s=polygon[0].y*(polygon[vcount-1].x-polygon[1].x);
    358 for (i=1;i<vcount;i++)
    359 s+=polygon[i].y*(polygon[(i-1)].x-polygon[(i+1)%vcount].x);
    360 return s/2;
    361 }
    362 // 判断顶点是否按逆时针排列
    363 // 如果输入顶点按逆时针排列,返回true
    364 bool isconterclock(int vcount,POINT polygon[])
    365 {
    366 return area_of_polygon(vcount,polygon)>0;
    367 }
    368 /*射线法判断点q与多边形polygon的位置关系
    369 要求polygon为简单多边形,顶点时针排列
    370 如果点在多边形内: 返回0
    371 如果点在多边形边上:返回1
    372 如果点在多边形外: 返回2 */
    373 int insidepolygon(POINT q)
    374 {
    375 int c=0,i,n;
    376 LINESEG l1,l2;
    377 l1.s=q; l1.e=q;l1.e.x=double(INF);
    378 n=vcount;
    379 for (i=0;i<vcount;i++)
    380 {
    381 l2.s=Polygon[i];
    382 l2.e=Polygon[(i+1)%vcount];
    383 double ee= Polygon[(i+2)%vcount].x;
    384 double ss= Polygon[(i+3)%vcount].y;
    385 if(online(l2,q))
    386 return 1;
    387 if(intersect_A(l1,l2))
    388 c++; // 相交且不在端点
    389 if(online(l1,l2.e)&& !online(l1,l2.s) && l2.e.y>l2.e.y)
    390 c++;//l2的一个端点在l1上且该端点是两端点中纵坐标较大的那个
    391 if(!online(l1,l2.e)&& online(l1,l2.s) && l2.e.y<l2.e.y)
    392 c++;//忽略平行边
    393 }
    394 if(c%2 == 1)
    395 return 0;
    396 else
    397 return 2;
    398 }
    399 //判断点q在凸多边形polygon内
    400 // 点q是凸多边形polygon内[包括边上]时,返回true
    401 // 注意:多边形polygon一定要是凸多边形
    402 bool InsideConvexPolygon(int vcount,POINT polygon[],POINT q)
    403 {
    404 POINT p;
    405 LINESEG l;
    406 int i;
    407 p.x=0; p.y=0;
    408 for(i=0;i<vcount;i++) // 寻找一个肯定在多边形polygon内的点p:多边形顶点平均值
    409 {
    410 p.x+=polygon[i].x;
    411 p.y+=polygon[i].y;
    412 }
    413 p.x /= vcount;
    414 p.y /= vcount;
    415 for(i=0;i<vcount;i++)
    416 {
    417 l.s=polygon[i];
    418 l.e=polygon[(i+1)%vcount];
    419 if(multiply(p,l.e,l.s)*multiply(q,l.e,l.s)<0)
    420 /* 点p和点q在边l的两侧,说明点q肯定在多边形外 */
    421 return false422 }
    423 return true424 }
    425 /*寻找凸包的graham 扫描法
    426 PointSet为输入的点集;
    427 ch为输出的凸包上的点集,按照逆时针方向排列;
    428 n为PointSet中的点的数目
    429 len为输出的凸包上的点的个数 */
    430 void Graham_scan(POINT PointSet[],POINT ch[],int n,int &len)
    431 {
    432 int i,j,k=0,top=2;
    433 POINT tmp;
    434 // 选取PointSet中y坐标最小的点PointSet[k],如果这样的点有多个,则取最左边的一个
    435 for(i=1;i<n;i++)
    436 if ( PointSet[i].y<PointSet[k].y || (PointSet[i].y==PointSet[k].y)
    437 && (PointSet[i].x<PointSet[k].x) )
    438 k=i;
    439 tmp=PointSet[0];
    440 PointSet[0]=PointSet[k];
    441 PointSet[k]=tmp; // 现在PointSet中y坐标最小的点在PointSet[0]
    442 for (i=1;i<n-1;i++) /* 对顶点按照相对PointSet[0]的极角从小到大进行排序,极角相同
    443 的按照距离PointSet[0]从近到远进行排序 */
    444 {
    445 k=i;
    446 for (j=i+1;j<n;j++)
    447 if ( multiply(PointSet[j],PointSet[k],PointSet[0])>0 || // 极角更小
    448 (multiply(PointSet[j],PointSet[k],PointSet[0])==0) && /*极角相等,距离更短 */ dist(PointSet[0],PointSet[j])<dist(PointSet[0],PointSet[k]) )
    449 k=j;
    450 tmp=PointSet[i];
    451 PointSet[i]=PointSet[k];
    452 PointSet[k]=tmp;
    453 }
    454 ch[0]=PointSet[0];
    455 ch[1]=PointSet[1];
    456 ch[2]=PointSet[2];
    457 for (i=3;i<n;i++)
    458 {
    459 while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;
    460 ch[++top]=PointSet[i];
    461 }
    462 len=top+1;
    463 }
    464 // 卷包裹法求点集凸壳,参数说明同graham算法
    465 void ConvexClosure(POINT PointSet[],POINT ch[],int n,int &len)
    466 {
    467 int top=0,i,index,first;
    468 double curmax,curcos,curdis;
    469 POINT tmp;
    470 LINESEG l1,l2;
    471 bool use[MAXV];
    472 tmp=PointSet[0];
    473 index=0;
    474 // 选取y最小点,如果多于一个,则选取最左点
    475 for(i=1;i<n;i++)
    476 {
    477 if(PointSet[i].y<tmp.y||PointSet[i].y == tmp.y&&PointSet[i].x<tmp.x)
    478 {
    479 index=i;
    480 }
    481 use[i]=false;
    482 }
    483 tmp=PointSet[index];
    484 first=index;
    485 use[index]=true;
    486 index=-1;
    487 ch[top++]=tmp;
    488 tmp.x-=100;
    489 l1.s=tmp;
    490 l1.e=ch[0];
    491 l2.s=ch[0];
    492 while(index!=first)
    493 {
    494 curmax=-100;
    495 curdis=0;
    496 // 选取与最后一条确定边夹角最小的点,即余弦值最大者
    497 for(i=0;i<n;i++)
    498 {
    499 if(use[i])continue;
    500 l2.e=PointSet[i];
    501 curcos=cosine(l1,l2); // 根据cos值求夹角余弦,范围在 (-1 -- 1 )
    502 if(curcos>curmax || fabs(curcos-curmax)<1e-6 && dist(l2.s,l2.e)>curdis)
    503 {
    504 curmax=curcos;
    505 index=i;
    506 curdis=dist(l2.s,l2.e);
    507 }
    508 }
    509 use[first]=false; //清空第first个顶点标志,使最后能形成封闭的hull
    510 use[index]=true;
    511 ch[top++]=PointSet[index];
    512 l1.s=ch[top-2];
    513 l1.e=ch[top-1];
    514 l2.s=ch[top-1];
    515 }
    516 len=top-1;
    517 }
    518 // 求凸多边形的重心,要求输入多边形按逆时针排序
    519 POINT gravitycenter(int vcount,POINT polygon[])
    520 {
    521 POINT tp;
    522 double x,y,s,x0,y0,cs,k;
    523 x=0;y=0;s=0;
    524 for(int i=1;i<vcount-1;i++)
    525 {
    526 x0=(polygon[0].x+polygon[i].x+polygon[i+1].x)/3;
    527 y0=(polygon[0].y+polygon[i].y+polygon[i+1].y)/3; //求当前三角形的重心
    528 cs=multiply(polygon[i],polygon[i+1],polygon[0])/2;
    529 //三角形面积可以直接利用该公式求解
    530 if(abs(s)<1e-20)
    531 {
    532 x=x0;y=y0;s+=cs;continue;
    533 }
    534 k=cs/s; //求面积比例
    535 x=(x+k*x0)/(1+k);
    536 y=(y+k*y0)/(1+k);
    537 s += cs;
    538 }
    539 tp.x=x;
    540 tp.y=y;
    541 return tp;
    542 }
    543 /*所谓凸多边形的直径,即凸多边形任两个顶点的最大距离。下面的算法
    544 仅耗时O(n),是一个优秀的算法。 输入必须是一个凸多边形,且顶点
    545 必须按顺序(顺时针、逆时针均可)依次输入。若输入不是凸多边形
    546 而是一般点集,则要先求其凸包。 就是先求出所有跖对,然后求出每
    547 个跖对的距离,取最大者。点数要多于5个*/
    548 void Diameter(POINT ch[],int n,double &dia)
    549 {
    550 int znum=0,i,j,k=1;
    551 int zd[MAXV][2];
    552 double tmp;
    553 while(amultiply(ch[0],ch[k+1],ch[n-1]) > amultiply(ch[0],ch[k],ch[n-1])-EP)
    554 k++;
    555 i=0;
    556 j=k;
    557 while(i<=k && j<n)
    558 {
    559 zd[znum][0]=i;
    560 zd[znum++][1]=j;
    561 while(amultiply(ch[i+1],ch[j+1],ch[i]) > amultiply(ch[i+1],ch[j],ch[i]) – EP
    562 && j< n-1)
    563 {
    564 zd[znum][0]=i;
    565 zd[znum++][1]=j;
    566 j++;
    567 }
    568 i++;
    569 }
    570 dia=-1.0;
    571 for(i=0;i<znum;i++)
    572 {
    573 printf("%d %d/n",zd[i][0],zd[i][1]);
    574 tmp=dist(ch[zd[i][0]],ch[zd[i][1]]);
    575 if(dia<tmp)
    576 dia=tmp;
    577 }
    578 } 
  • 相关阅读:
    洛谷P1306 斐波那契公约数
    Codevs 1688 求逆序对(权值线段树)
    poj1006 Biorhythms
    2017-9-2 NOIP模拟赛
    洛谷P1633 二进制
    洛谷P2513 [HAOI2009]逆序对数列
    洛谷P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower
    洛谷P2285 [HNOI2004]打鼹鼠
    2017-8-31 NOIP模拟赛
    洛谷P2134 百日旅行
  • 原文地址:https://www.cnblogs.com/lovebay/p/10470238.html
Copyright © 2011-2022 走看看