Wannafly挑战赛15 E-小W的斜率

链接: https://www.nowcoder.com/acm/contest/112/E
来源:牛客网

题目描述

小W非常喜欢某个有理数P/Q,而且他非常喜欢用它来进行一些玄学操作。他在二维平面上撒下了n个点,这些点相互不同,但一番观察之后,他失望的发现并没有任何两个点连成的直线的斜率是P/Q。你能不能告诉他在这些斜率中最接近P/Q的是多少。

输入描述:

 
  

第一行包括三个正整数n,P,Q(5<=n<=106,1<=P,Q<=105)

接下来n行,每行两个正整数x,y表示点的坐标(0<=x,y<=109)

输出描述:

一个有理数P’/Q’表示最接近P/Q的斜率

题解:
求(y2-y1)/(x2-x1)最接近P/Q,移项得Q*y2-P*x2最近接Q*y1-P*x1
排序,判断相邻的两项即可。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+7;
struct node
{
    ll x,y,s;
} c[maxn];
ll gcd(ll a,ll b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
bool cmp(const node &a,const node &b)
{
    return a.s<b.s;
}
int main()
{
    ll n,P,Q;
    scanf("%lld%lld%lld",&n,&P,&Q);
    for(int i=0; i<n; i++)
    {
        scanf("%lld%lld",&c[i].x,&c[i].y);
        c[i].s=Q*c[i].y-P*c[i].x;
    }
    sort(c,c+n,cmp);
    double mi=1e18;
    ll a,b;
    for(int i=1; i<n; i++)
    {
        ll x1=c[i].x-c[i-1].x;
        ll y1=c[i].y-c[i-1].y;
        if(x1<0)
            x1=-x1;
        if(y1<0)
            y1=-y1;
        double s=fabs(1.00*y1/x1-1.00*P/Q);
        if(s<mi)
        {
            mi=s;a=x1,b=y1;
        }
    }
    ll g=gcd(a,b);
    printf("%lld/%lld\n",b/g,a/g);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/albertluf/article/details/80292395