您的位置:首页 > 其它

HDU 5295 Unstable

2015-08-10 10:45 399 查看
problem

题意

题意非常简单,给定AB,BC,CD,DA,EF五条线段的长度,确定这五个点的坐标。其中E是AB的中点,F是CD的中点。有SPJ,所以只要满足这五条线段长度的点就可以了。

思路

非常纯净的一道几何题。。我们假设我们已经得到了这个四边形。对这个四边形做先做以下的操作:连接AF,倍长至A’。连接A’B,A’C,过A’做BC平行线,过B做A’C平行线,交于G。连接GD。如下图。



从这个图形我们可以得到一些性质。观察三角形
BCA'
,我们可以知道,这个三角形的三条边分别为
BC,AD,2*EF
,也就是说这个三角形是确定的。我们从这里入手,先确定
BC
两点的坐标(任意即可),然后以
B
为圆心做一个半径为
2EF
的圆,以
C
为圆心做一个长度为
DA
的圆。这样我们就确定了
A'
。再根据
A'
来确定
G
点的坐标。然后以
G
为圆心,做一个半径为
AB
的圆,以
C
为圆心,确定长度为
CD
的圆。这两圆的交点为
D
。然后
A
也可以求出来了。

AC代码

HDU5295

/*************************************************************************
> File Name: main.cpp
> Author: znl1087
> Mail: loveCJNforever@gmail.com
> Created Time: 日  8/ 9 13:33:25 2015
************************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
using namespace std;
const double PI = acos(-1.0);
const double EPS = 1.5e-6;
struct Point{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
};
typedef Point Vec;
int dcmp(double x){
if(fabs(x) < EPS) return 0; else return x < 0 ? -1: 1;
}
Vec operator + (Vec a,Vec b){return Vec(a.x + b.x, a.y + b.y);}
Vec operator - (Vec a,Vec b){return Vec(a.x - b.x, a.y - b.y);}
Vec operator * (Vec a,double p){return Vec(a.x * p,a.y * p);}
Vec operator / (Vec a,double p){return Vec(a.x / p,a.y / p);}
bool operator == (const Point& a,const Point& b){
return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y)==0;
}
double angle(Vec v){return atan2(v.y,v.x);}

double Dot(Vec a,Vec b){return a.x * b.x + a.y * b.y;}
double Length(Vec a){return sqrt(Dot(a,a));}
double Angle(Vec a,Vec b){return acos(Dot(a,b)/Length(a)/Length(b));}
double Cross(Vec a,Vec b){return a.x * b.y - a.y * b.x;}

struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c,double r):c(c),r(r){}
Point point(double a){
return Point(c.x + cos(a) * r , c.y + sin(a) * r);
}
};

int getCircleCircleIntersection(Circle C1,Circle C2,vector<Point>& sol){
double d = Length(C1.c - C2.c);
if( dcmp(C1.r - C2.r)>0)
swap(C1,C2);
if(dcmp(d) == 0){
if(dcmp(C1.r - C2.r)==0){
sol.push_back(C1.c + Vec(0,C1.r));
sol.push_back(C1.c - Vec(0,C1.r));
return 2;
}
return 0;
}
if(dcmp(C1.r + C2.r - d) < 0) return 0;
if(dcmp(fabs(C1.r - C2.r)-d) > 0)return 0;
if(dcmp(C1.r + C2.r - d) == 0 || dcmp(fabs(C1.r - C2.r)-d) == 0){
Vec p = C1.c-C2.c;
sol.push_back(C2.c + p / Length(p) * C2.r);
return 1;
}
double a = angle(C2.c - C1.c);
double da = acos((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d));
Point p1 = C1.point(a-da),p2 = C1.point(a+da);
sol.push_back(p1);
if(p1 == p2)return 1;
sol.push_back(p2);
return 2;
}
double AB,BC,CD,DA,EF;
int main(){
int T;
cin>>T;
for(int cas = 1;cas <= T;cas++){
scanf("%lf%lf%lf%lf%lf",&AB,&BC,&CD,&DA,&EF);
Circle B = Circle(Point(0,0),2*EF),C = Circle(Point(0,BC),DA),G,D;
Point A,A2;
vector<Point> ans;
int ok = getCircleCircleIntersection(B, C,ans);
for(int ook = 0;ook<ok;ook++){
A2 = ans[ook];
G = Circle(A2 + (B.c - C.c),AB);
C.r = CD;
ans.clear();
int flag = getCircleCircleIntersection(C, G, ans);
if(flag == 0)continue;
D = Circle(ans[0],DA);
//printf("GD:%lf\n",Length(G.c-D.c));
A = B.c + (D.c-G.c);
printf("Case #%d:\n",cas);
printf("%.6f %.6f\n",A.x,A.y);
printf("%.6f %.6f\n",B.c.x,B.c.y);
printf("%.6f %.6f\n",C.c.x,C.c.y);
printf("%.6f %.6f\n",D.c.x,D.c.y);
Point E = (A + B.c)/2.0,F = (C.c + D.c)/2.0;
/*printf("AB:%lf BC:%lf CD:%lf DA:%lf EF:%lf\n",
Length(A-B.c),Length(B.c-C.c),Length(C.c-D.c),
Length(D.c-A),Length(E-F));*/
break;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: