您的位置:首页 > 其它

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

2017-05-31 00:37 369 查看
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*=sca
4000
le, 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: