码迷,mamicode.com
首页 > 其他好文 > 详细

CF598C Nearest vectors

时间:2018-11-30 00:39:28      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:ati   col   string   函数   read   bsp   printf   print   static   

题目描述

  有n个点,每个点表示原点到该点的向量,让你求出两个向量最小的夹角,输出向量的序号

 

此题其实不难,只需把每个向量与x轴的非负半轴的逆时针角度求出来,排序后,相邻的角度相减,取最小值即可。

但是难在atan我并没有接触过,atan2是一个函数,返回的是指方位角(弧度制),计算时atan2 比 atan 稳定。

返回的值取值范围为 技术分享图片 ,所以我们在得到的值小于0时要加上2π

另外要注意的是,函数atan2(y,x)中参数的顺序是倒置的,atan2(y,x)计算的值相当于点(x,y)的角度值。

实现如下:

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long ll;
inline int read()
{
    register int p(1),a(0);register char ch=getchar();
    while((ch<0||ch>9)&&ch!=-) ch=getchar();
    if(ch==-) p=-1,ch=getchar();
    while(ch>=0&&ch<=9) a=a*10+ch-48,ch=getchar();
    return a*p;
}
const int N=100100;
const long double pai=atan2(0.0,-1.0);
int n,jl;
struct node
{
    int xu;
    long double x,y,du;
    bool operator < (const node &xx)const{return du<xx.du;}
}a[N];
long double maxn=9999999.0;
int main()
{
//    freopen("input","r",stdin);
//    freopen("output","w",stdout);
    n=read();
    for(int i=1;i<=n;i++)
    {
        a[i].xu=i;
        a[i].x=read(),a[i].y=read();
        a[i].du=atan2(a[i].y,a[i].x);
        if(a[i].du<0.0) a[i].du=a[i].du+pai+pai;
    }
    sort(a+1,a+1+n);
    for(int i=2;i<=n;i++)
        if(maxn>min(a[i].du-a[i-1].du,pai+pai-a[i].du+a[i-1].du))
        {
            maxn=min(a[i].du-a[i-1].du,pai+pai-a[i].du+a[i-1].du);
            jl=i;
        }
    if(maxn>min(a[n].du-a[1].du,pai+pai-a[n].du+a[1].du)) jl=1;
    printf("%d %d\n",a[jl].xu,jl-1==0?a[n].xu:a[jl-1].xu);
    return 0;
}

 

CF598C Nearest vectors

标签:ati   col   string   函数   read   bsp   printf   print   static   

原文地址:https://www.cnblogs.com/cold-cold/p/10041583.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!