Rescue The Princess 山东省赛题 求三角形顶点 atan2求解

来源:互联网 发布:淘宝云客服培训 编辑:程序博客网 时间:2024/06/05 09:54

题目链接: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;}




0 0
原创粉丝点击