题目链接:hdu 5476
今天和队友们搞出3道水题后就一直卡在这儿了,唉,真惨啊……看着被一名一名地挤出晋级名次,确实很不好受,这道恶心的几何题被我们3个搞了3、4个小时,我想到一半时发现样例输出是 (√2) π / 2 + 1, 于是就各种 YY,无奈尝试了各种方法还是免不了 wa。。。
后来在网上发现,那段圆弧其实就和自己插身而过,真的可以说差一点就想到了,无奈到了最后我们几个都精疲力尽了,好像也想不出什么了。看下图:
就是三角形里的圆弧的长度,设为 Lc ,很容易得出 Lc = | OC | * 2 * ∠O,而 ∠O = ∠ACM,∠ACM可以由 | AM | 与 | CM | 的 atan 值求出,而 | OC | = | CM | / sin(∠O),所以,核心代码就几行而已:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std; struct point {
double x,y;
point() {}
point(double x, double y): x(x), y(y) {}
void read() { scanf("%lf %lf",&x,&y); }
void readint() {
int x,y;
scanf("%d %d",&x,&y);
this->x = x;
this->y = y;
}
point operator + (const point &p2) const {
return point(x + p2.x, y + p2.y);
}
point operator - (const point &p2) const {
return point(x - p2.x, y - p2.y);
}
point operator * (double p) const {
return point(x * p, y * p);
}
point operator / (double p) const {
return point(x / p, y / p);
}
}; typedef point Vector;
typedef const point& cpoint;
typedef const Vector& cvector; point operator * (double p, Vector a) {
return a * p;
} double dot(cvector a, cvector b) {
return a.x * b.x + a.y * b.y;
} double length(cvector a) {
return sqrt(dot(a,a));
} double angle(cvector a, cvector b) {
return acos(dot(a,b) / length(a) / length(b));
} double cross(cvector a, cvector b) {
return a.x * b.y - a.y * b.x;
} const double PI = acos(-1.0); int main() {
int t, Case = ;
point a,b,c;
scanf("%d",&t);
while(t--) {
a.readint();
b.readint();
c.readint();
point m = (b + c) / ;
double am = length(m - a), cm = length(m - c);
double angO = atan(am / cm);
double oc = cm / sin(angO);
double ans = oc * * angO + am;
printf("Case #%d: %.4f\n",++Case,ans);
}
return ;
}
附上证明截图:(刚刚看懂,好强大~~ Orz Orz)