规范相交

  1. 规范相交:两条线段恰有一个不是端点的公共点。

    即如果一条线段的一个端点恰在另一条线段上则不视为相交;如果两条线段部分重合,也不视为相交。

    非规范相交:两条线段存在公共部分。(上述两种情况都可视为非规范相交)

    其中a~f是非规范相交; g,h是不相交; a~c有唯一的交点;d~f有无数个交点。


  2. #define eps 1e-8  
  3. struct point  
  4. {  
  5. double x;  
  6. double y;  
  7. };  
  8. double multi(point p0, point p1, point p2)//j计算差乘  
  9. {   return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}  
  10. bool is_cross(point s1,point e1,point s2,point e2)//判断线段是否相交(非规范相交)  
  11. {  
  12.    return max(s1.x,e1.x) >= min(s2.x,e2.x)&&  
  13.           max(s2.x,e2.x) >= min(s1.x,e1.x)&&  
  14.           max(s1.y,e1.y) >= min(s2.y,e2.y)&&  
  15.           max(s2.y,e2.y) >= min(s1.y,e1.y)&&  
  16.           multi(s1,e1,s2)*multi(s1,e1,e2) <= 0&&  
  17.           multi(s2,e2,s1)*multi(s2,e2,e1) <= 0;  
  18. }  

2 判断直线与线段相交

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. bool across(point &a,point &b,point &c,point &d)//直线ab和线段cd是否相交  
  2. {  
  3. double p=xmulit(a,b,c),p1=xmulit(a,b,d);  
  4. if( fabs(p1) <= eps || fabs(p) <= eps ) return true;  
  5. if( p*p1 <= 1e-8 )  
  6. return true;  
  7. return false;  
  8. }  
  9. bool is_equal(point &a,point &b)//判断点a和点b是否相等  
  10. {  
  11. return (fabs(a.x-b.x) <= eps) && (fabs(a.y-b.y) <=eps);  
  12. }  


3 判断结果是否为0

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. bool zero(double a)//判断结果是否为0  
  2. {  
  3. return fabs(a) <= eps;  
  4. }  


4 判断两直线是否平行

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. bool parallel(line &u,line &v)//判断直线u和直线v是否平行  
  2. {  
  3. return zero((u.a.x-u.b.x)*(v.a.y-v.b.y) - (v.a.x-v.b.x)*(u.a.y-u.b.y));  
  4. }  
  5.   
  6. bool parallel(point &u1,point &u2,point &v1,point &v2)//判断直线u1 u2 and v1 v2 是否平行  
  7. {  
  8. return zero((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));  
  9. }  

5 判断点是否在直线上

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. bool dot_in_line(point &a,point &b,point &c)  
  2. {  
  3. return parallel(b,a,a,c);  
  4. }  

6 求两直线的交点 注意是直线不是线段

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. point intersection(line &u,line &v)  
  2. {  
  3. point ret=u.a;  
  4. double t=((u.a.x-v.a.x)*(v.a.y-v.b.y) - (u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));  
  5. ret.x+=(u.b.x-u.a.x)*t;  
  6. ret.y+=(u.b.y-u.a.y)*t;  
  7. return ret;  
  8. }  

判断线段是否相交

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. bool on_segment(point pi,point pj,point pk)//判断点pk是否在线段pi, pj上  
  2. {  
  3.     if(xmulit(pi, pj, pk)==0)  
  4.     {  
  5.         if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y))  
  6.             return true;  
  7.     }  
  8.     return false;  
  9. }  
  10. bool segments_intersect(point p1,point p2,point p3,point p4)//判断线段是否相交  
  11. {  
  12.     double d1=xmulit(p3,p4,p1);  
  13.     double d2=xmulit(p3,p4,p2);  
  14.     double d3=xmulit(p1,p2,p3);  
  15.     double d4=xmulit(p1,p2,p4);  
  16.     if(d1*d2<0&&d3*d4<0)  
  17.         return true;  
  18.     else if(d1==0&&on_segment(p3,p4,p1))  
  19.         return true;  
  20.     else if(d2==0&&on_segment(p3,p4,p2))  
  21.         return true;  
  22.     else if(d3==0&&on_segment(p1,p2,p3))  
  23.         return true;  
  24.     else if(d4==0&&on_segment(p1,p2,p4))  
  25.         return true;  
  26.     return false;  
  27. }  


7 求凸包的graham扫描法

输入n表示有多少个点

接下来n个点的坐标

example:

输入:

9

200 400

300 400

300 300

400 300

400 400

500 400

500 200

350 200

200 200

输出:

500.000000 200.000000
500.000000 400.000000
400.000000 400.000000
300.000000 400.000000
200.000000 400.000000
200.000000 200.000000

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4. #include <algorithm>  
  5. #include <cmath>  
  6. using namespace std;  
  7. #define eps 1e-6  
  8. #define PI 3.14159265  
  9. struct point  
  10. {  
  11. double x;  
  12. double y;  
  13. }po[1500],temp;  
  14. int n,pos;  
  15. bool zero(double a)  
  16. {  
  17. return fabs(a) < eps;  
  18. }  
  19. double dis(point &a,point &b)//返回两点之间距离的平方  
  20. {  
  21. return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);  
  22. }  
  23. double across(point &a,point &b,point &c)//求a b and a c 的X积  
  24. {  
  25. return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x);  
  26. }  
  27. int cmp(const void *a,const void *b)  
  28. {  
  29. return across(po[0],*(point*)a,*(point*)b) > 1e-8 ? -1 : 1;  
  30. }  
  31. int select()  
  32. {  
  33. int i,j,k=1;  
  34. for(i=2;i<n;i++)  
  35. {  
  36. if(zero(across(po[0],po[k],po[i])))  
  37. {  
  38. if(dis(po[0],po[k]) < dis(po[0],po[i]))  
  39. po[k]=po[i];  
  40. }  
  41. else  
  42. po[++k]=po[i];  
  43. }  
  44. return k+1;  
  45. }  
  46. int graham(int num)  
  47. {  
  48. int i,j,k=2;  
  49. //  
  50. po[num]=po[0];//fangbian   
  51. num++;  
  52. for(i=3;i<num;i++)  
  53. {  
  54. while(across(po[k-1],po[k],po[i]) < -eps)  
  55. {k--;}  
  56. po[++k]=po[i];//就这个循环结束,不需要了!  
  57. }  
  58. for(i=0;i<k;i++)  
  59. printf("%lf %lf\n",po[i].x,po[i].y);  
  60. return 0;  
  61. }  
  62. int main()  
  63. {  
  64. int i,j,k;  
  65. point my_temp;  
  66. while(scanf("%d",&n)!=EOF)  
  67. {  
  68. scanf("%lf%lf",&po[0].x,&po[0].y);  
  69. temp=po[0];  
  70. pos=0;  
  71. for(i=1;i<n;i++)  
  72. {  
  73. scanf("%lf%lf",&po[i].x,&po[i].y);  
  74. if(po[i].y < temp.y)  
  75. temp=po[i],pos=i;  
  76. }  
  77. my_temp=po[0];  
  78. po[0]=po[pos];  
  79. po[pos]=my_temp;  
  80. qsort(po+1,n-1,sizeof(po[0]),cmp);  
  81. graham(select());  
  82. }  
  83. return 0;  
  84. }  

最近平面点对 见其他博客


给定一个多边形判断是否为凸包

要求逆时针给定多边形的各个顶点

放在po数组中

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. struct point  
  2. {  
  3. int x;  
  4. int y;  
  5. }po[1000];  
  6. int across(point &a,point &b,point &c)  
  7. {  
  8. return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);  
  9. }  
  10. int is_convex(int num,point *p)  
  11. {  
  12. int i;  
  13. p[num]=p[0];  
  14. num++;  
  15. p[num]=po[1];  
  16. num++;  
  17. int count=0;  
  18. for(i=2;i < num;i++){  
  19. if(across(p[i-2],p[i-1],p[i]) < 0)  
  20. return 0;  
  21. }  
  22. return 1;  
  23. }  

已知正方形的一条边的两点坐标,求另外两点的坐标

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. 已知: (x1,y1)  (x2,y2)  
  2. 则:   x3=x1+(y1-y2)   y3= y1-(x1-x2)  
  3. x4=x2+(y1-y2)   y4= y2-(x1-x2)  
  4. 或  
  5. x3=x1-(y1-y2)   y3= y1+(x1-x2)  
  6. x4=x2-(y1-y2)   y4= y2+(x1-x2)  



扩展KMP 模板

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include<iostream>  
  2. #include<string>  
  3. using namespace std;  
  4. const int MM=100005;  
  5. int next[MM],extand[MM];  
  6. char S[MM],T[MM];  
  7. void GetNext(const char *T){  
  8.      int len=strlen(T),a=0;  
  9.      next[0]=len;  
  10.      while(a<len-1 && T[a]==T[a+1]) a++;  
  11.      next[1]=a;  
  12.      a=1;  
  13.      for(int k=2;k<len;k++){  
  14.          int p=a+next[a]-1,L=next[k-a];  
  15.          if( (k-1)+L >= p){  
  16.              int j = (p-k+1)>0 ? (p-k+1) : 0;  
  17.              while(k+j<len && T[k+j]==T[j]) j++;  
  18.              next[k]=j;  
  19.              a=k;   
  20.          }   
  21.          else  
  22.              next[k]=L;   
  23.      }   
  24. }   
  25. void GetExtand(const char *S,const char *T){  
  26.      GetNext(T);  
  27.      int slen=strlen(S),tlen=strlen(T),a=0;   
  28.      int MinLen = slen < tlen ? slen : tlen;  
  29.      while(a<MinLen && S[a]==T[a]) a++;  
  30.      extand[0]=a;  
  31.      a=0;  
  32.      for(int k=1;k<slen;k++){  
  33.          int p=a+extand[a]-1, L=next[k-a];  
  34.          if( (k-1)+L >= p){  
  35.              int j= (p-k+1) > 0 ? (p-k+1) : 0;  
  36.              while(k+j<slen && j<tlen && S[k+j]==T[j]) j++;  
  37.              extand[k]=j;  
  38.              a=k;   
  39.          }  
  40.          else   
  41.              extand[k]=L;   
  42.      }   
  43. }   
  44. int main(){  
  45.     while(scanf("%s%s",S,T)==2){  
  46.          GetExtand(S,T);  
  47.          for(int i=0;i<strlen(T);i++)  
  48.              printf("%d ",next[i]);  
  49.          puts("");  
  50.          for(int i=0;i<strlen(S);i++)  
  51.              printf("%d ",extand[i]);  
  52.          puts("");   
  53.     }   
  54.     return 0;  
  55. }  


欧拉四面体公式 :HDU 1411 

注意输入点边的长度依次是:AB,AC,AD,BC,BD,CD

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <iostream>  
  2. #include <string.h>  
  3. #include <cmath>  
  4. #include <stdio.h>  
  5. #include <algorithm>  
  6. using namespace std;  
  7. double l,m,n,p,q,r;  
  8. double area()  
  9. {  
  10.     return sqrt((p*p*(q*q*r*r-((q*q+r*r-l*l)/2)*((q*q+r*r-l*l)/2))  
  11.     +((p*p+r*r-m*m)/2)*(((p*p+q*q-n*n)/2)*((q*q+r*r-l*l)/2)-((p*p+r*r-m*m)/2)*q*q)  
  12.     -((p*p+q*q-n*n)/2)*(((p*p+q*q-n*n)/2)*r*r-((p*p+r*r-m*m)/2)*(q*q+r*r-l*l)/2))/36);  
  13. }  
  14. int main()  
  15. {  
  16.     while(scanf("%lf%lf%lf%lf%lf%lf",&n,&m,&p,&l,&q,&r)!=EOF)  
  17.     {  
  18.       printf("%.4lf\n",area());  
  19.     }  
  20.     return 0;  
  21. }  


求两个圆相交部分的面积:HDU 3264

函数area

 a:第一个圆心 r1 第一个圆的半径

 b:第二个圆心 r2 第二个圆的半径             

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. struct point  
  2. {  
  3.  double x;  
  4.  double y;  
  5. };  
  6. double area(point a,double r1,point b,double r2)  
  7. {  
  8.  double d=sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));//圆心距  
  9.  if(r1>r2)  
  10.  {  
  11.  double temp=r1;  
  12.  r1=r2;  
  13.  r2=temp;  
  14.  }//r1取小  
  15.  if(r1+r2<=d)  
  16.  return 0;//相离  
  17.  else if(r2-r1>=d)  
  18.  return pi*r1*r1;//内含  
  19.  else  
  20.  {  
  21.  double a1=acos((r1*r1+d*d-r2*r2)/(2.0*r1*d));  
  22.  double a2=acos((r2*r2+d*d-r1*r1)/(2.0*r2*d));  
  23.  return (a1*r1*r1+a2*r2*r2-r1*d*sin(a1));  
  24.  }//相交  
  25. }  



多边形重心模板适合任意多边形,但是多边形的边要顺序给出!

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. point gravity(point *p, int n)  
  2. {  
  3. double area = 0;  
  4. point center;  
  5. center.x = 0;  
  6. center.y = 0;  
  7. for (int i = 0; i < n-1; i++)  
  8. {  
  9.    area += (p[i].x*p[i+1].y - p[i+1].x*p[i].y)/2;  
  10.    center.x += (p[i].x*p[i+1].y - p[i+1].x*p[i].y) * (p[i].x + p[i+1].x);  
  11.    center.y += (p[i].x*p[i+1].y - p[i+1].x*p[i].y) * (p[i].y + p[i+1].y);  
  12. }  
  13. area += (p[n-1].x*p[0].y - p[0].x*p[n-1].y)/2;  
  14. center.x += (p[n-1].x*p[0].y - p[0].x*p[n-1].y) * (p[n-1].x + p[0].x);  
  15. center.y += (p[n-1].x*p[0].y - p[0].x*p[n-1].y) * (p[n-1].y + p[0].y);  
  16. center.x /= 6*area;  
  17. center.y /= 6*area;  
  18. return center;  
  19. }  


点到线段之间距离 线段到线段之间距离


[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. double point_to_seg(point a,point b,point c)//c 到直线a-b的距离    
  2. {    
  3.     point ab,ac;    
  4.     ab.x=b.x-a.x;    
  5.     ab.y=b.y-a.y;    
  6.     ac.x=c.x-a.x;    
  7.     ac.y=c.y-a.y;    
  8.     double f=dot(ab,ac);    
  9.     if(f<0)return dis(a,c);    
  10.     double f1=dot(ab,ab);    
  11.     if(f>f1)return dis(b,c);    
  12.     f=f/f1;    
  13.     point d;    
  14.     d.x=a.x+ab.x*f;    
  15.     d.y=a.y+ab.y*f;    
  16.     return dis(d,c);    
  17. }    
  18. double seg_to_seg(point a1,point b1,point a2,point b2)  // a1-b1    a2-b2  
  19. {    
  20.     return min(min(point_to_seg(a1,b1,a2),point_to_seg(a1,b1,b2)),min(point_to_seg(a2,b2,a1),point_to_seg(a2,b2,b1)));    
  21. }    



判断点是否在多边形内部a表示要判断的那个点,po是多边形(按一定顺序)点集,n多边形点的个数

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. int inpoto(point a,point *po,int n)//判断点是否在多边形的内部    
  2. {    
  3.     int i;    
  4.     point b,c,d;    
  5.     b.y=a.y;    
  6.     b.x=1e15;//定义射线    
  7.     int flag=0;    
  8.     int count=0;    
  9.     for(i=0;i<n;i++)    
  10.     {    
  11.         c = po[i];    
  12.         d = po[i + 1];    
  13.         if(on_segment(c,d,a))//该点在多边形的一条边上    
  14.             return 1;    
  15.         if(abs(c.y-d.y)<eps)    
  16.             continue;    
  17.         if(on_segment(a,b,c))//和顶点相交的情况,如果y值较大则取    
  18.         {    
  19.             if(c.y>d.y)    
  20.                 count++;    
  21.         }    
  22.         else if(on_segment(a,b,d))//和顶点相交的情况,如果y值较大则取    
  23.         {    
  24.             if(d.y>c.y)    
  25.                 count++;    
  26.         }    
  27.         else if(segments_intersect(a,b,c,d))//和边相交    
  28.             count++;    
  29.     }    
  30.     return count%2;//当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。    
  31. }    

求任意多边形与圆的相交部分的面积

a b 多边形上所有边的两个顶点 c圆心 r 半径

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #define eps 1e-8  
  2. struct Point  
  3. {  
  4.     double x,y;  
  5. };  
  6. double x_mult(Point sp, Point ep, Point op)  
  7. {  
  8.     return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);  
  9. }  
  10. double cross(Point a,Point b,Point c)  
  11. {  
  12.     return (a.x-c.x)*(b.x-c.x)+(a.y-c.y)*(b.y-c.y);  
  13. }  
  14. double dist(Point a,Point b)  
  15. {  
  16.     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));  
  17. }  
  18. double cal_area(Point a,Point b,Point c,double r)//a b多边形上所有边的两个端点 c圆心 r半径  
  19. {  
  20.     double A,B,C,x,y,tS;  
  21.     A=dist(b,c);  
  22.     B=dist(a,c);  
  23.     C=dist(b,a);  
  24.     if(A<r&&B<r)  
  25.     return x_mult(a,b,c)/2;  
  26.     else if(A<r&&B>=r)  
  27.     {  
  28.         x=(cross(a,c,b)+sqrt(r*r*C*C-x_mult(a,c,b)*x_mult(a,c,b)))/C;  
  29.         tS=x_mult(a,b,c)/2;  
  30.         return asin(tS*(1-x/C)*2/r/B*(1-eps))*r*r/2+tS*x/C;  
  31.     }  
  32.     else if(A>=r&&B<r)  
  33.     {  
  34.         y=(cross(b,c,a)+sqrt(r*r*C*C-x_mult(b,c,a)*x_mult(b,c,a)))/C;  
  35.         tS=x_mult(a,b,c)/2;  
  36.         return asin(tS*(1-y/C)*2/r/A*(1-eps))*r*r/2+tS*y/C;  
  37.     }  
  38.     else if(fabs(x_mult(a,b,c))>=r*C||cross(b,c,a)<=0||cross(a,c,b)<=0)  
  39.     {  
  40.         if(cross(a,b,c)<0)  
  41.             if(x_mult(a,b,c)<0)  
  42.                 return (-acos(-1.0)-asin(x_mult(a,b,c)/A/B*(1-eps)))*r*r/2;  
  43.             else return (acos(-1.0)-asin(x_mult(a,b,c)/A/B*(1-eps)))*r*r/2;  
  44.         else return asin(x_mult(a,b,c)/A/B*(1-eps))*r*r/2;  
  45.     }  
  46.     else  
  47.     {  
  48.         x=(cross(a,c,b)+sqrt(r*r*C*C-x_mult(a,c,b)*x_mult(a,c,b)))/C;  
  49.         y=(cross(b,c,a)+sqrt(r*r*C*C-x_mult(b,c,a)*x_mult(b,c,a)))/C;  
  50.         tS=x_mult(a,b,c)/2;  
  51.         return (asin(tS*(1-x/C)*2/r/B*(1-eps))+asin(tS*(1-y/C)*2/r/A*(1-eps)))*r*r/2+tS*((y+x)/C-1);  
  52.     }  
  53. }  

·

坐标绕原点旋转公式新坐标公式(x,y)->(x1,y1)

x1=cos(angle)*x-sin(angle)*y;

y1=sin(angle)*x+cos(angle)*y;


点集的最小圆覆盖


[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /*http://blog.sina.com.cn/s/blog_5caa94a001015dr3.html*/  
  2. #include<stdio.h>  
  3. #include<math.h>  
  4. #include<string.h>  
  5. #define MAXN 20  
  6. struct pointset{  
  7.     double x, y;  
  8. };  
  9. const double precison=1.0e-8;  
  10. pointset maxcic, point[MAXN];  
  11. double radius;  
  12. int curset[MAXN], posset[3];  
  13. int set_cnt, pos_cnt;  
  14. inline double dis_2(pointset &from, pointset& to){  
  15.     return ((from.x-to.x)*(from.x-to.x)+(from.y-to.y)*(from.y-to.y));  
  16. }  
  17. int in_cic(int pt){  
  18.     if(sqrt(dis_2(maxcic, point[pt]))<radius+precison) return 1;  
  19.     return 0;  
  20. }  
  21. int cal_mincic(){  
  22.     if(pos_cnt==1 || pos_cnt==0)  
  23.         return 0;  
  24.     else if(pos_cnt==3){  
  25.         double A1, B1, C1, A2, B2, C2;  
  26.         int t0=posset[0], t1=posset[1], t2=posset[2];  
  27.         A1=2*(point[t1].x-point[t0].x);  
  28.         B1=2*(point[t1].y-point[t0].y);  
  29.         C1=point[t1].x*point[t1].x-point[t0].x*point[t0].x+  
  30.             point[t1].y*point[t1].y-point[t0].y*point[t0].y;  
  31.         A2=2*(point[t2].x-point[t0].x);  
  32.         B2=2*(point[t2].y-point[t0].y);  
  33.         C2=point[t2].x*point[t2].x-point[t0].x*point[t0].x+  
  34.             point[t2].y*point[t2].y-point[t0].y*point[t0].y;  
  35.         maxcic.y=(C1*A2-C2*A1)/(A2*B1-A1*B2);  
  36.         maxcic.x=(C1*B2-C2*B1)/(A1*B2-A2*B1);  
  37.         radius=sqrt(dis_2(maxcic, point[t0]));  
  38.     }  
  39.     else if(pos_cnt==2){  
  40.         maxcic.x=(point[posset[0]].x+point[posset[1]].x)/2;  
  41.         maxcic.y=(point[posset[0]].y+point[posset[1]].y)/2;  
  42.         radius=sqrt(dis_2(point[posset[0]], point[posset[1]]))/2;  
  43.     }  
  44.     return 1;  
  45. }  
  46. int mindisk(){  
  47.     if(set_cnt==0 || pos_cnt==3){  
  48.         return cal_mincic();  
  49.     }  
  50.     int tt=curset[--set_cnt];  
  51.     int res=mindisk();  
  52.     set_cnt++;  
  53.     if(!res || !in_cic(tt)){  
  54.         set_cnt--;  
  55.         posset[pos_cnt++]=curset[set_cnt];  
  56.         res=mindisk();  
  57.         pos_cnt--;  
  58.         curset[set_cnt++]=curset[0];  
  59.         curset[0]=tt;  
  60.     }  
  61.     return res;  
  62. }  
  63. int main(){  
  64.     int n;  
  65.     while(scanf("%d", &n)!=EOF){  
  66.         if(n==0) break;  
  67.         int i;  
  68.         for(i=0; i<n; i++)  
  69.             scanf("%lf %lf", &point[i].x, &point[i].y);  
  70.             if(n==1){  
  71.                 maxcic.x=point[0].x;  
  72.                 maxcic.y=point[0].y;  
  73.                 radius=0;  
  74.                 printf("%.2lf %.2lf %.2lf\n", maxcic.x, maxcic.y, radius);  
  75.                 continue;  
  76.             }  
  77.             set_cnt=n; pos_cnt=0;  
  78.             for(i=0 ;i<n ;i++)  curset[i]=i;  
  79.             mindisk();  
  80.             printf("%.2lf %.2lf %.2lf\n", maxcic.x, maxcic.y, radius);  
  81.     }  
  82.   
  83.     return 0;  
  84. }  


求ab 和ac的夹角

这个求出来的结果只是两个向量之间夹角小的那个,如果想求顺时针的可以判断ab和cd的时针关系,如果ab在cd的逆时针方向,用PI*2去减

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. double angle(point a, point b, point c) {  
  2.   double ux = b.x - a.x, uy = b.y - a.y;  
  3.   double vx = c.x - a.x, vy = c.y - a.y;  
  4.   return acos((ux*vx + uy*vy) /  
  5.               sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy)));  
  6. }  
[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. #include <string.h>  
  2. #include <stdio.h>  
  3. #include <algorithm>  
  4. #include <iostream>  
  5. #include <cmath>  
  6. using namespace std;  
  7. const double PI=acos(-1.0);  
  8. struct point{  
  9.     double x,y;  
  10. };  
  11. double angle(point a, point b, point c) {  
  12.   double ux = b.x - a.x, uy = b.y - a.y;  
  13.   double vx = c.x - a.x, vy = c.y - a.y;  
  14.   return acos((ux*vx + uy*vy) /  
  15.               sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy)));  
  16. }  
  17. double cross(point &a,point &b,point &c){  
  18.     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);  
  19. }  
  20. int main(){  
  21.     int i,j,k;  
  22.     point a,b,c;  
  23.     c.x=c.y=0;  
  24.     double my_angle,ans;  
  25.     while(scanf("%lf %lf %lf %lf",&a.x,&a.y,&b.x,&b.y)!=EOF){  
  26.         my_angle=angle(c,a,b);  
  27.         if(cross(c,a,b)<0){  
  28.             printf("YES\n");  
  29.             my_angle=PI*2-my_angle;  
  30.         }  
  31.         ans=180*my_angle/PI;  
  32.         printf("%lf\n",ans);  
  33.     }  
  34.     return 0;  
  35. }  


POJ 2954 PICK定理

[cpp]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. /*整点多边形面积=多边形内含点数+边上整点数/2-1 
  2. 外边界上的整点个数可以根据GCD来求,具体看代码 
  3. 题意:给你一个整点三角的三个顶点让你求三角形内部整点个数 
  4. */  
  5. #include <stdio.h>  
  6. #include <string.h>  
  7. #include <algorithm>  
  8. #include <iostream>  
  9. using namespace std;  
  10. struct point{  
  11.     int x,y;  
  12. }a,b,c;  
  13. int gcd(int a,int b){  
  14.     if(a<b) a^=b,b^=a,a^=b;  
  15.     if(b==0) return a;  
  16.     return gcd(b,a%b);  
  17. }  
  18. int cross(point &a,point &b,point &c){  
  19.     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);  
  20. }  
  21. int main(){  
  22.     int i,j,k,num;  
  23.     while(scanf("%d%d%d%d%d%d",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y)){  
  24.         if(a.x==0 && b.x==0 && c.x==0 && a.y==0 && b.y==0 && c.y==0)  
  25.         return 0;  
  26.         num=gcd(abs(a.x-b.x),abs(a.y-b.y))+gcd(abs(a.x-c.x),abs(a.y-c.y))+gcd(abs(c.y-b.y),abs(c.x-b.x));  
  27.         k=cross(a,b,c);  
  28.         printf("%d\n",(abs(k)-num+2)/2);  
  29.     }  
  30.     return 0;  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值