sicily 1012. Stacking Cylinders

//纯计算题,三角形内,已知两点坐标A(x1,y1),B(x2,y2),求第三点的坐标C(x3,y3),其中顶点A,B到C距离都为2
//由 (x3-x1)^2+(y3-y1)^2=4 和 (x3-x2)^2+(y3-y2)^2=4
//可得 2(x2-x1)*x3+2(y2-y1)*y3=x2^2-x1^2+y2^2-y1^2 (1)
//设A,B距离为L,则顶点C到直线AB的距离 H=2*sin<CAB=2*√(1-L^2/16)
//再应用点( x0,y0)到直线ax+by+c=0 的距离公式 |ax0+by0+c|/√(a^2+b^2)
//可得 H=| 1/(x2-x1) *x3 - 1/(y2-y1) *y3 -x2/(x2-x1)+y2/(y2-y1) | / √(1/(x2-x1)^2+1/(y2-y1)^2) (2)
//联立(1)(2),即可求解

#include
<iostream> //计算几何
#include<cmath>
#include
<stdio.h>
#include
<algorithm>
using namespace std;
double x[4],y[4];
int cmp(const void *a,const void *b)
{
return ((double *)a)[0] > ((double *)b)[0] ?1:-1 ;
}
void cross(double o,double p,double q,double r)
{
x[
1]=o;y[1]=p;x[2]=q;y[2]=r;

if(y[1]==y[2])
{
x[
3]=(x[1]+x[2])/2.0;
y[
3]=y[1]+2*sqrt(1-pow(x[2]-x[1],2.0)/16.0);
return ;
}

double a[3],b[3],c[3],temp;
a[
1]=2*(x[2]-x[1]);b[1]=2*(y[2]-y[1]);c[1]=x[2]*x[2]-x[1]*x[1]+y[2]*y[2]-y[1]*y[1];
a[
2]=1.0/(x[2]-x[1]);b[2]=-1.0/(y[2]-y[1]);
temp
=2*sqrt(1.0-(pow(x[2]-x[1],2.0)+pow(y[2]-y[1],2.0))/16.0)*sqrt(1.0/pow((x[2]-x[1]),2.0)+1.0/pow((y[2]-y[1]),2.0));
c[
2]=temp+x[2]/(x[2]-x[1])-y[2]/(y[2]-y[1]);
x[
3]=(c[1]*b[2]-c[2]*b[1])/(a[1]*b[2]-a[2]*b[1]);y[3]=(a[2]*c[1]-a[1]*c[2])/(b[1]*a[2]-a[1]*b[2]);

if(y[3]<y[1]||y[3]<y[2]) //点(x0,y0)到直线ax+by+c=0 的距离公式 |ax0+by0+c| / √(a^2+b^2) ,其中有绝对值符号
{
c[
2]=-temp+x[2]/(x[2]-x[1])-y[2]/(y[2]-y[1]);
x[
3]=(c[1]*b[2]-c[2]*b[1])/(a[1]*b[2]-a[2]*b[1]);y[3]=(a[2]*c[1]-a[1]*c[2])/(b[1]*a[2]-a[1]*b[2]);
}
}
int main()
{
double arr[2][20][2];
int cs,s;
cin
>>cs;
for(int i=1;i<=cs;++i)
{
cin
>>s;
int id=0;
for(int j=1;j<=s;++j)
{
cin
>>arr[id][j][0];
arr[id][j][
1]=1.0;
}
qsort(arr[id]
+1,s,sizeof(arr[id][1]),cmp); //要先排序
while(s>1)
{
for(int j=1;j<s;++j)
{
cross(arr[id][j][
0],arr[id][j][1],arr[id][j+1][0],arr[id][j+1][1]);
arr[(id
+1)%2][j][0]=x[3];arr[(id+1)%2][j][1]=y[3]; //滚动数组
}
id
=(id+1)%2;
s
--;
}
printf(
"%d: %0.4lf %0.4lf\n",i,arr[id][1][0],arr[id][1][1]);
}
return 0;
}

posted on 2011-07-04 18:17  sysu_mjc  阅读(288)  评论(0编辑  收藏  举报

导航