题目大意:看题目戳我
这个题目的意思我真的看了好久……(自己英文太差真心太菜嘤嘤嘤)。其实就是给你几个向量,要你找出哪两个向量的夹角最小,输出这两个向量你输入时的序号(是的没错是序号。。。)index我记住了。。。说好的是指数的意思呢。
题目收获:
这道题要求的精度比较高,记得要开long double,然后有一个很方便的函数 atan2(),
函数声明:
long double atan2(long double y,long double x)
返回的是原点至点(x,y)的方位角,即与 x 轴正向的夹角。也可以理解为复数 x+yi 的辐角。
返回值的单位为弧度,取值范围为 (-PI,PI]。
然后又查了一下另一个反正切函数 atan(),atan()只有一个参数
double atan(double x)
其中x是一个直线的斜率,返回的是这个直线与x轴正向夹角的弧度值;例如:
int main(void)
{
double k;
double tri;
cin>>k;
tri=atan(k);
cout<<tri<<endl;
return 0;
}
题目思路:
有了atan2()这个函数,我们就可以计算出所给的向量分别与x轴正向的夹角,然后排序之后,计算两两之间的夹角就好了,特别注意一下计算最小的和最大的“真正夹角”,有可能一个在y轴负半轴一个在正半轴,这时会出现他们两个夹角其实是小于“大角-小角”
题目代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define maxn 100005
#define PI acos(-1.0)
using namespace std;
struct coo
{
long double val;
int pos;
}r[maxn];
int cmp(coo a,coo b)
{
return a.val<b.val;
}
int main(void)
{
//cout<<PI<<endl;
int n;
int u1,u2;
long double minn=50;
long double x,y;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>x>>y;
r[i].val=atan2(x,y);
r[i].pos=i+1;
}
sort(r,r+n,cmp);
for(int i=1;i<n;i++)
{
long double mid=r[i].val-r[i-1].val;
if(mid<minn)
{
minn=mid;
u1=r[i].pos;
u2=r[i-1].pos;
}
}
long double xx;
if(r[0].val<0&&r[n-1].val>0)//2PI-
{
xx=2*PI-(r[n-1].val-r[0].val);
if(xx<minn)//如果最小角和最大角夹角比minn小
{
u1=r[0].pos;
u2=r[n-1].pos;
}
}
printf("%d %d\n",u1,u2);
return 0;
}
呼呼