牛客小白月赛21 - Audio(求三角形外心)
牛客小白月赛21 - Audio(求三角形外心)
链接:https://ac.nowcoder.com/acm/contest/3947/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
Nancy很喜欢音乐。
她能同时分辨出三种不同的音乐。恰巧,一座城市中有三处同时有交响音乐会(音源响度相同)。但是Nancy每一场都不想错过,于是她想寻找一个地点,使得三处音乐会声音的响度相同,这样她就可以同时欣赏三场音乐会啦!
(注:假设声音传播过程中不会受障碍物作用,声音传播满足平方反比定律)
她能同时分辨出三种不同的音乐。恰巧,一座城市中有三处同时有交响音乐会(音源响度相同)。但是Nancy每一场都不想错过,于是她想寻找一个地点,使得三处音乐会声音的响度相同,这样她就可以同时欣赏三场音乐会啦!
(注:假设声音传播过程中不会受障碍物作用,声音传播满足平方反比定律)
输入描述:
共三行:每行两个整数xi与yi,三点不共线。
数据满足:0≤∣xi∣,∣yi∣≤109。
输出描述:
共一行:两个实数posx,posy,表示Nancy欣赏音乐会的地点(保留三位小数)
输入
0 0 1 3 4 2
输出
2.000 1.000
计算几何基础,原本不想整理的,后来看到有一篇博客写的挺清楚的,还是转载下吧
from:https://blog.nowcoder.net/n/ea2af8cf56314da7aacd99ef38c5da11
解法一:
根据点的距离和关系,直接解方程
1 #include <bits/stdc++.h> 2 typedef long long LL; 3 const int INF=0x3f3f3f3f; 4 const double eps =1e-8; 5 const int mod=1e8; 6 const int maxn=2e5+10; 7 using namespace std; 8 9 int main() 10 { 11 #ifdef DEBUG 12 freopen("sample.txt","r",stdin); 13 #endif 14 15 double x1,x2,x3,y1,y2,y3; 16 scanf("%lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&x3,&y3); 17 18 double A1,B1,C1,A2,B2,C2; 19 A1 = 2*(x2-x1); 20 B1 = 2*(y2-y1); 21 C1 = x2*x2+y2*y2-x1*x1-y1*y1; 22 A2 = 2*(x3-x1); 23 B2 = 2*(y3-y1); 24 C2 = x3*x3+y3*y3-x1*x1-y1*y1; 25 26 double X = (C2-B2*C1/B1)/(A2-B2*A1/B1); 27 double Y = (C1-A1*X)/B1; 28 29 printf("%.3f %.3f\n",X,Y); 30 31 return 0; 32 }
解法二:
我们需要求一点,使得该点到三角形三个顶点距离相同,即求三角形的外心(三边中垂线交点)。
我们需要求出任意两条边的垂直平分线,联立他们再求交点即可。
推导:
给定一线段y=kx+b(一端坐标为(x1,y1),另一端坐标为(x2,y2)),求其垂直平分线的函数解析式
设其中垂线为f=k1x+c
∵f⊥y
∴k1*k = -1,即k1 = -1/k(注:若两直线互相垂直,则k1*k2=-1)
∴f = -1/k*x+c,即f = -x/k+c;
把点((x1+x2)/2,(y1+y2)/2)代入f = -x/k+c中
得(y1+y2)/2 = -((x1+x2)/2)/k+c
化简得c = (y1+y2)/2+(x1+x2)/2k
∴f = -x/k+c代入c即得
f = -x/k+(x1+x2)/2k+(y1+y2)/2
代入k =(y1-y2)/(x1-x2)即得中垂线解析式
(设经过(x1,y1),(x2,y2)两点的解析式为y = kx+b,则由y1 = kx1+b,y2 = kx2+b两式相减可得k)
1 #include <bits/stdc++.h> 2 typedef long long LL; 3 const int INF=0x3f3f3f3f; 4 const double eps =1e-8; 5 const int mod=1e8; 6 const int maxn=2e5+10; 7 using namespace std; 8 9 int main() 10 { 11 #ifdef DEBUG 12 freopen("sample.txt","r",stdin); 13 #endif 14 15 double x1,x2,x3,y1,y2,y3; 16 scanf("%lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&x3,&y3); 17 18 double k,k1,b1,k2,b2; 19 k = (y1-y2)/(x1-x2); 20 k1 = -1/k; b1 = (x1+x2)/2/k+(y1+y2)/2; 21 k = (y1-y3)/(x1-x3); 22 k2 = -1/k; b2 = (x1+x3)/2/k+(y1+y3)/2; 23 24 double X = (b2-b1)/(k1-k2); 25 double Y = k1*X+b1; 26 27 printf("%.3f %.3f\n",X,Y); 28 29 return 0; 30 }
-