BZOJ 3621: 我想那还真是令人高兴啊 计算几何 复数
https://www.lydsy.com/JudgeOnline/problem.php?id=3621
给定两个三角形,其中一个可以通过以某点为中心旋转并放缩的方式得到另一个,求这个中心
https://blog.csdn.net/PoPoQQQ/article/details/44346555
↑题解见这个博客。
get到了复数的特殊用法,原来旋转缩放都可以用复数实现的。因为复数相乘是极角相加、长度相乘,所以把点放到复平面上之后可以用一个复数点T代表缩放和旋转的系数,一个复数点P为中心点,列方程验证就行了。
我太智障了,最开始写的代码的验证方式特别复杂精度还有问题(我为什么要算出来三个中心点然后把三个中心点都比较一遍啊有毒吧),看了dalao的代码发现自己真实智障完全不用比较那么多,算出来两个比一下就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<complex> 7 using namespace std; 8 #define LL long long 9 const double eps=0.0001; 10 typedef complex< double >cd; 11 cd a[2][3]; 12 inline double mabs(double x){return x<0?(-x):x;} 13 int main(){ 14 //freopen("a.in","r",stdin); 15 int T;scanf("%d",&T); 16 while(T-->0){ 17 double x,y; 18 for(int i=0;i<2;++i){ 19 for(int j=0;j<3;j++){ 20 scanf("%lf%lf",&x,&y); 21 a[i][j]=cd(x,y); 22 } 23 } 24 cd ans=0;bool f=0; 25 for(int i=0;i<3;i++){ 26 for(int j=0;j<3;j++){ 27 if(i==j)continue; 28 cd z=(a[1][i]-a[1][j])/(a[0][0]-a[0][1]); 29 int w=3-i-j; 30 cd po=(a[0][0]*z-a[1][i])/(z-1.0); 31 cd zz=(a[0][2]-po)*z-(a[1][w]-po); 32 if(mabs(zz.real())<eps&&mabs(zz.imag())<eps){ans=po;f=1;break;} 33 } 34 if(f)break; 35 } 36 printf("%.4f %.4f\n",ans.real(),ans.imag()); 37 } 38 return 0; 39 }