和吴昊一起玩推理 Round 8 —— 计算几何一系列(C)—— 圆上知道一点求另外两点组成一个周长最长的三角形(HDOJ 1700)

 

 Source: HDOJ 1700

 

【数学证明】 

  设R是圆半径,A,B,C是三角形的角,由正弦定理得a/sinA =b/sinB=c/sinC=2R
故a+b+c=2R(sinA+sinB+sinC),当R确定求周长a+b+c最大,归结为求sinA+sinB+sinC的最大.
设Y=sinA+sinB+sinC,先固定角A,
Y=sinA+sinB+sinC=sinA+2sin((B+C)/2)cos((B-C)/2)
=sinA+2cos(A/2)cos((B-C)/2)
因为A是定值,故只有B=C时,Y才有最大值,同理分别再固定角B,C,则当C=A,A=B时,
Y才有最大值,故A=B=C=60时,Y值最大,即周长a+b+c最大.
也即同圆或等圆中周长最大的三角形是等边三角形.

 

 
  1 【一般方法】
  2 
  3  
  4 
  5   #include<stdio.h>
  6 #include<math.h>
  7 #define pi acos(-1.0)
  8 #define epx 0.0005
  9 int main()
 10 {
 11  int t;
 12  double x1,y1,x2,y2,x3,y3,a,r,b;
 13  scanf("%d",&t);
 14  while(t--&&scanf("%lf%lf",&x1,&y1))
 15  {
 16    r=sqrt(x1*x1+y1*y1);
 17    if(x1!=0&&y1!=0)
 18    {
 19     if(x1<0&&y1<0)a=pi+atan(y1/x1);
 20     else if(x1<0&&y1>0)a=pi+atan(y1/x1);
 21     else a=atan(y1/x1);
 22    }
 23    else if(x1==0&&y1!=0)
 24    {
 25       if(y1>0)a=pi/2;
 26       else a=-pi/2;
 27    }
 28    else if(x1!=0&&y1==0)
 29    {
 30     if(x1>0)a=0;
 31     else a=pi;
 32    }
 33    b=2*pi/3+a;
 34    x2=cos(b)*r;y2=sin(b)*r;
 35    x3=-(x1+x2);y3=-(y1+y2);
 36    if(fabs(y2-y3)<epx)
 37    {
 38     if(x2<x3)printf("%.3lf %.3lf %.3lf %.3lf\n",x2,y2,x3,y3);
 39   else printf("%.3lf %.3lf %.3lf %.3lf\n",x3,y3,x2,y2);  
 40    }
 41    else
 42    {
 43      if(y2<y3)printf("%.3lf %.3lf %.3lf %.3lf\n",x2,y2,x3,y3);
 44   else printf("%.3lf %.3lf %.3lf %.3lf\n",x3,y3,x2,y2);
 45    }
 46  }
 47 }
 48 
 49  
 50 【复平面方法】
 51  
 52 #include<stdio.h>
 53 #include<math.h>
 54 #define s sqrt(3.0)
 55 #define epx 0.0005
 56 int main()
 57 {
 58  int t;
 59  double x1,y1,x2,y2,x3,y3,a,r,b;
 60  scanf("%d",&t);
 61  while(t--&&scanf("%lf%lf",&x1,&y1))
 62  {
 63    x2=-(x1+s*y1)/2;
 64    y2=(s*x1-y1)/2;
 65    x3=-(x1+x2);y3=-(y1+y2);
 66    if(fabs(y2-y3)<epx)
 67    {
 68     if(x2<x3)printf("%.3lf %.3lf %.3lf %.3lf\n",x2,y2,x3,y3);
 69   else printf("%.3lf %.3lf %.3lf %.3lf\n",x3,y3,x2,y2);  
 70    }
 71    else
 72    {
 73      if(y2<y3)printf("%.3lf %.3lf %.3lf %.3lf\n",x2,y2,x3,y3);
 74   else printf("%.3lf %.3lf %.3lf %.3lf\n",x3,y3,x2,y2);
 75    }
 76  }
 77 }
 78 
 79 【向量法】
 80 
 81  设 P(x,y),一个方程是pow(x,2)+pow(y,2)=pow(r,2);另一个方程是根据向量知识,向量的夹角公式得到方程。因为圆心角夹角 为120度,已知一个向量(即一个点作标),所以COS(2PI/3)=a*b/|a|*|b|;(a,b为向量);已知角和a向量,就可求b向量 b(x,y).由方程组可求得(x,y);最后得到的是一元二次方程组,可得到两个解,即为两个点的作标。
 82 
 83 #include<stdio.h>
 84 #include<math.h>
 85 struct Point
 86 {
 87 double x;
 88 double y;
 89 };
 90 int main()
 91 {
 92 Point p1,p2,p3;
 93 double a,b,c,r,delta;
 94 int t,i;
 95 for (;scanf("%d",&t)!=EOF;)
 96 {
 97 for (i=0;i<t;i++)
 98 {
 99 scanf("%lf%lf",&p1.x,&p1.y);
100 r=sqrt(p1.x*p1.x+p1.y*p1.y);
101 a=p1.x*p1.x+p1.y*p1.y;
102 b=p1.y*r*r;
103 c=(-p1.x*p1.x*r*r+r*r*r*r/4);
104 delta=b*b-4*a*c;
105 p2.y=(-1*b-sqrt(delta))/(2*a);
106 p3.y=(-1*b+sqrt(delta))/(2*a);
107 if(p1.x==0)
108 {
109 p2.x=-sqrt(r*r-p2.y*p2.y);
110 p3.x=sqrt(r*r-p2.y*p2.y);
111 }
112 else
113 {
114 p2.x=(-1*r*r/2-p1.y*p2.y)/p1.x;
115 p3.x=(-1*r*r/2-p1.y*p3.y)/p1.x;
116 }
117 
118 printf("%.3lf %.3lf %.3lf %.3lf\n",p2.x,p2.y,p3.x,p3.y);
119 }
120 }
121 return 0;
122 }
123 【方程组法】
124 
125 已知一个以(00)为圆心的圆和圆上的一点(x0,y0)求圆上的另外两点(x1,y1,)(x2,y2),使得向量(x1,y1)(x2,y2)和(x0,y0)各个向量两两之间夹角为120度
126 
127 此题主要用到向量的叉乘和点乘列出两个二元一次方程组
128 
129 1.
130 
131 (x0,y0)X (x1,y1) = sin(120)*R^2 (r为圆的半径)
132 
133 (x0,y0) * (x1,y1) = cos(120)*R^2
134 
135 结果为:
136 
137 x1=b*x0-a*y0; a=sin120
138 y1=b*y0+a*x0; b=cos120;
139 
140 2.
141 
142 (x0,y0)X (x2,y2) = -sin(120)*R^2 (r为圆的半径)
143 
144 (x0,y0) * (x2,y2) = cos(120)*R^2
145 
146 注:题目假设向量(x1,y1)在向量(x0,y0)逆时针方向 故叉乘结果为正值
147 
148 (x2,y2)于(x0,y0)的顺时针方向 故叉乘结果为负值
149 
150 #include <stdlib.h>
151 #include <stdio.h>
152 #include <math.h>
153 int main(int argc, char** argv) {
154 
155 
156 double a,b,sinx,cosx,x0,y0,x1,y1,x2,y2;
157 int t;
158 
159 a=sinx=sqrt(3.0)/2;
160 b=cosx=-0.5;
161 scanf("%d",&t);
162 while(t--)
163 {
164 scanf("%lf%lf",&x0,&y0);
165 
166 x1=b*x0-a*y0;
167 y1=b*y0+a*x0;
168 x2=b*x0+a*y0;
169 y2=b*y0-a*x0;
170 if(y1<y2||((abs(y1-y2)<0.005)&&x1<x2))
171 {
172 printf("%.3lf %.3lf %.3lf %.3lf\n",x1,y1,x2,y2);
173 }
174 else
175 printf("%.3lf %.3lf %.3lf %.3lf\n",x2,y2,x1,y1);
176 
177 }
178 
179 return (EXIT_SUCCESS);
180 }

posted on 2013-02-27 22:43  吴昊系列  阅读(327)  评论(0编辑  收藏  举报

导航