6290. 倾斜的线

Description

Input

Output

Sample Input

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

Sample Output

193409386/235911335
 

Data Constraint

Solution

题意是给你n个点和P,Q,要你求两个点构成的斜率最接近于P/Q,以“A/B”的形式输出斜率。
相当于是然你求(y1-y2)/(x1-x2) 最接近于P/Q的值X和Y。
通分,得到:
Q(y1-y2)/Q (x1-x2)最接近于P(x1-x2)/Q(x1-x2)
将分母去掉:
Q(y1-y2)最接近于P(x1-x2)
拆项:
Qy1-Qy2最接近于Px1-Px2
移项:
Qy1-Px1最接近于Qy2-Px2

至此,我们只用对每一个点的上式排一遍序,去相邻的比较即可。

考虑另一种思路。

我们将式子拆成:
| Q(y1-y2) / Q(x1-x2)-P(x1-x2) / Q(x1-x2) |最小

| ((Q(y1-y2)-P(x1-x2)) / Q(x1-x2) |最小

| ((Qy1-Px1)-(Qy2-Px2)) / Qx1-Qx2 |最小

我们将这个式子看成斜率的形式,
即Q(y1-Px1)=Y1,Q(y2-Px2)=Y2,Qx1=X1,Qx2=X2,得:
| (Y1-Y2)/(X1-X2) | 最小
也就是我们将每个点用上式变成一个新点,再求两个点所构成的斜率的绝对值最小值。
若两个纵坐标直接有一个点,那么这中间点于两边点构成的斜率总有一个会比两边点构成的斜率小。
因此我们将点按照纵坐标排序,
用两两相邻的纵坐标更新答案即可。

注意精度问题。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define I int
#define F(i,a,b) for(I i=a;i<=b;i++)
#define Fd(i,a,b) for(I i=a;i>=b;i--)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define N 200010
#define db long double
using namespace std;
ll n,P,Q,Ax,Ay,d;
db ans=1e17;
struct node{ll x,y,z;}a[N];
ll gcd(ll x,ll y){
	if(x%y==0) return y;
	return gcd(y,x%y);
}
I cmp(node a,node b){return a.z>b.z;}
db S(db x){
	if(x<0) return -x;
	return x;
}
I main(){
	freopen("slope.in","r",stdin);
	freopen("slope.out","w",stdout);
	scanf("%lld%lld%lld",&n,&P,&Q);
	F(i,1,n){
		scanf("%lld%lld",&a[i].x,&a[i].y);
		a[i].z=Q*a[i].y-P*a[i].x;
	}
	sort(a+1,a+1+n,cmp);
	F(i,1,n-1){
		db s=S((db)(a[i].y-a[i+1].y)/(db)(a[i].x-a[i+1].x)-(db)P/(db)Q);
		if(ans>s){
			ans=s;
			Ax=a[i].y-a[i+1].y;
			Ay=a[i].x-a[i+1].x;
		}
	}
	d=gcd(Ax,Ay);
	printf("%lld/%lld\n",Ax/d,Ay/d);
	return 0;
}

 



作者:zsjzliziyang 
QQ:1634151125 
转载及修改请注明 
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/99697172

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值