题目链接:http://acm.upc.edu.cn/problem.php?id=2217
一拿到该题,并不知道,有atan2这个函数,所以只能解方程组求解了,结果耗费了大量的时间才写出来,而且代码比较冗长,真是有些蛋疼。下面说说atan2这个函数的用法吧:
atan2(delta y,delta x),感觉应该是这样的一种形式,刚开始以为这是用来求直线的斜率的,但从试用的情况来看,并不是这样,而是用来求向量的倾斜角的:
当向量向上是为正值,当向量向下时为负值。
只要知道了这个结论,那么此题就变得比较容易了,仔细分析给定向量的四种情况,可以得到一个通用求解表达式,见代码。
代码:
#include<iostream>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<string>
#define LL long long
#define INF 0x7fffffff
//freopen("D:\\in.txt","r",stdin);
using namespace std;
double x[3],y[3];
int main(){
int T;cin>>T;
while(T--){
cin>>x[1]>>y[1]>>x[2]>>y[2];
double t=sqrt(pow(x[1]-x[2],2.0)+pow(y[2]-y[1],2.0));
double r=atan2(y[2]-y[1],x[2]-x[1]);
r+=3.1415926535897932384626/3;
printf("(%.2lf,%.2lf)\n",x[1]+t*cos(r),y[1]+t*sin(r));//四种情况都满足
}
return 0;
}
顺便附上我写的数学求解代码(太长了):
#include<iostream>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<string>
#define LL __int64
#define INF 0x7fffffff
//freopen("D:\\in.txt","r",stdin);
using namespace std;
double x[3],y[3],t,p,q,tq,a,b,c,X,Y;
void disp(double s,double delta){
double ty=(y[1]+y[2])/2;
for(int i=-1;i<=1;i+=2){
X=s+i*delta;Y=X*p+q;//由于是二元的,会有不满足条件的解,需要判断,而且还得是逆时针方向
if(x[1]<x[2] && Y>ty){printf("(%.2lf,%.2lf)\n",X,Y);;return;}
if(x[1]>x[2] && Y<ty){printf("(%.2lf,%.2lf)\n",X,Y);;return;}
}
}
void disp2(int n){
double ans[2];
for(int i=-1;i<=1;i+=2){
if(n==1){
ans[n]=y[1]+i*t*sqrt(3)/2;
ans[1-n]=(x[1]+x[2])/2;
if(x[1]<x[2] && ans[n]>y[1]) {
printf("(%.2lf,%.2lf)\n",ans[0],ans[1]);
return;
}
if(x[1]>x[2] && ans[n]<y[1]){
printf("(%.2lf,%.2lf)\n",ans[0],ans[1]);
return;
}
}
else {
ans[n]=x[1]+i*t*sqrt(3)/2;
ans[1-n]=(y[1]+y[2])/2;
if(y[1]>y[2] && ans[n]>x[1]) {
printf("(%.2lf,%.2lf)\n",ans[0],ans[1]);
return;
}
if(y[1]<y[2] && ans[n]<x[1]){
printf("(%.2lf,%.2lf)\n",ans[0],ans[1]);
return;
}
}
}
}
int main(){
int T;cin>>T;
while(T--){
cin>>x[1]>>y[1]>>x[2]>>y[2];
t=sqrt((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2]));
if(x[1]==x[2]) {disp2(0);continue;}//斜率为0和90度时单独求解
if(y[1]==y[2]){disp2(1);continue;}
p=(x[2]-x[1])/(y[1]-y[2]);//否则利用方程组求出第三点的解
q=(x[1]*x[1]-x[2]*x[2]+y[1]*y[1]-y[2]*y[2])/(2*(y[1]-y[2]));
tq=q-y[1];
a=1+p*p;b=2*(p*tq-x[1]);c=x[1]*x[1]+tq*tq-t*t;
double delta=sqrt(b*b-4*a*c)/(2*a),s=-1*b/(2*a);
disp(s,delta);
}
return 0;
}