计蒜客 第四场 C 商汤科技的行人检测(中等)平面几何好题

来源:互联网 发布:java设计模式的书籍 编辑:程序博客网 时间:2024/04/29 16:35

转 http://blog.csdn.net/johsnows/article/details/72803284

大佬真强

中文题..
https://nanti.jisuanke.com/t/15552
解题思路:
n^2枚举点对,然后根据这对点算出四个参数,然后重新跑一遍点,判断有多少个点的变换符合这个四个参数,超过一半就正确直接输出。
具体的算法。
scale 两个点之间的距离跟旋转和平移都没有关系,然后根据相似三角形可以知道两点之间距离的变化就是scale。

坐标旋转量θ:旋转坐标前两个点形成的直线向量A,和旋转坐标后的两个点形成的直线向量B,A,B的夹角就是θ,可以证明,这里就不说了,然后用一下公式cosθ=A*B/(|A|*|B|), 就能算出角度了。

dx,dy用scale和θ算出的坐标和题目给的坐标一减就出来了

。。真强。。。这位大佬高中数学肯定贼好。。数学弱只能感受一波了,原来利用任意两个点 本来->变化后,可以求出这么多东西,可以求出伸缩量,利用旧的两点距离和新的亮点距离成比例就好,还有就是角度,利用旧的线的旋转角度后变成新的线的角度(。。强。。然后就可以利用 A*B/(|A|*|B|) 求出角度了。。涨知识。。虽然不知道会记住多少。。加油加油)

A,B 都为两点相减。
坑点:一定要输出10位以后,scanf一定要%lf 输出%lf 或者 %.11f 都可以

#include <bits/stdc++.h>using namespace std;const double eps=1e-4;//判断精度为 1e-3 所以判到1e-4 是可以的struct node{    double x,y;    double xx,yy;}s[1000];double dis(double x, double y, double a, double b)  {      return sqrt((x-a)*(x-a)+(y-b)*(y-b));  }  bool judge(double x, double y, double a, double b, double ang,double scale, double dx, double dy)  {      double xx, yy;      xx=x*cos(ang)-y*sin(ang);      yy=x*sin(ang)+y*cos(ang);      xx*=scale, yy*=scale;      xx+=dx, yy+=dy;      if(fabs(xx-a)<=eps && fabs(yy-b)<=eps)return true;      else return false;  }  int main(){    int n;    scanf("%d",&n);    int m=n/2;    if(n&1)        m++;    for(int i=0;i<n;i++){        scanf("%lf%lf%lf%lf",&s[i].x,&s[i].y,&s[i].xx,&s[i].yy);        //无敌坑 scanf 一定要%lf    }    if(n==1)    {        printf("0.00000000000\n1.00000000000\n%.11f %.11f\n",s[0].xx-s[0].x,s[0].yy-s[0].y );        return 0;    }    double ang,scale,dx,dy;    for(int i=0;i<n/2+1;i++)    {        for(int e=0,j=i+1;j<n;j++,e++)        {            if(e>=n/2) break;            ang=0,scale=0,dx,dy;            // double dis1=dis(s[i].x, s[i].y, s[j].x, s[j].y);                         // double dis2=dis(s[i].xx, s[i].yy, s[j].xx, s[j].yy);              // scale=dis2/dis1;              double dis1=dis(s[i].x,s[i].y,s[j].x,s[j].y);            double dis2=dis(s[i].xx,s[i].yy,s[j].xx,s[j].yy);            scale=dis2/dis1;            // double x1=s[j].x-s[i].x, y1=s[j].y-s[i].y;              // double x2=s[j].xx-s[i].xx, y2=s[j].yy-s[i].yy;              // double A=dis(x1, y1, 0.0, 0.0);              // double B=dis(x2, y2, 0.0, 0.0);              // ang=acos((x1*x2+y1*y2)/(A*B));              double x1=s[j].x-s[i].x,y1=s[j].y-s[i].y;            double x2=s[j].xx-s[i].xx,y2=s[j].yy-s[i].yy;            double A=dis(x1,y1,0.0,0.0);            double B=dis(x2,y2,0.0,0.0);            ang=acos((x1*x2+y1*y2)/(A*B));            //   dx=s[i].xx-scale*(s[i].x*cos(ang)-s[i].y*sin(ang));              // dy=s[i].yy-scale*(s[i].x*sin(ang)+s[i].y*cos(ang));              dx=s[i].xx-(scale)*(s[i].x*cos(ang)-s[i].y*sin(ang));            dy=s[i].yy-(scale)*(s[i].x*sin(ang)+s[i].y*cos(ang));            int cnt=0;            int ff=0;            int flag=0;            for(int k=0;k<n;k++)            {                int res=judge(s[k].x,s[k].y,s[k].xx,s[k].yy,ang,scale,dx,dy);                if(res==1)                    cnt++;                else ff++;                if(ff>=n/2)                    break;            }            if(cnt>=m)            {                printf("%.11f\n%.11f\n%.11f %.11f\n",ang,scale,dx,dy);                return 0;            }        }    }    printf("%.11f\n%.11f\n%.11f %.11f\n", ang, scale, dx, dy);      return 0;}
阅读全文
0 0
原创粉丝点击