列表

详情


NC15915. 小W的斜率

描述

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的斜率

示例1

输入:

6 15698 17433
112412868 636515040
122123982 526131695
58758943 343718480
447544052 640491230
162809501 315494932
870543506 895723090

输出:

193409386/235911335

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 710ms, 内存消耗: 15932K, 提交时间: 2021-07-17 10:08:53

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,x,y;
struct node{
    ll x;
    ll y;
}a[1000050];
//bool cmp(node a,node b){
   // return abs(a.x*y-a.y*x)<abs(b.x*y-b.y*x);
//}
int main()
{
    cin>>n>>x>>y;
    double k=x*1.0/y;
    for(int i=0;i<n;i++)
        cin>>a[i].x>>a[i].y;
    //sort(a,a+n,cmp);
    ll ax,ay;
    double min1;
    for(int i=1;i<n;i++){
        ll ry=a[i].y-a[i-1].y;
        ll rx=a[i].x-a[i-1].x;
        double rk=1.0*ry/rx;
        if(i==1||min1>abs(rk-k)){
            min1=abs(rk-k);
            ax=rx;
            ay=ry;
        }
    }
    cout<<ay/__gcd(ax,ay)<<"/"<<ax/__gcd(ax,ay)<<endl;
}

C++14(g++5.4) 解法, 执行用时: 535ms, 内存消耗: 15976K, 提交时间: 2019-11-16 23:01:42

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
ll n,p,q,L=1,R;
bool cmp(ll a,ll b,ll c,ll d){return fabs(1.0*a/b-1.0*p/q)<fabs(1.0*c/d-1.0*p/q);}
int main(){
	scanf("%lld%lld%lld",&n,&p,&q);
	vector<pll>vec(n);
	for(int i=0;i<n;++i)scanf("%lld%lld",&vec[i].first,&vec[i].second);
	sort(vec.begin(),vec.end(),[p,q](pll a,pll b){return q*a.second-p*a.first<q*b.second-p*b.first;});
	for(int i=0;i+1<n;++i){
		ll a=vec[i+1].second-vec[i].second,b=vec[i+1].first-vec[i].first;
		if(!b)continue;
		if(a<0&&b<0)a=-a,b=-b;
		if(cmp(a,b,L,R))L=a,R=b;
	}
	ll g=__gcd(L,R);
	printf("%lld/%lld\n",L/g,R/g);
	return 0;
}

上一题