Description
详见OJ
Solution
考场上推式子,看能否有仅包含一个点的值。
然后推到后面推出来一个用(abs(Q(y1-y2)-P(x1-x2)))的大小来比接近程度。
然后按(Qy-Px)排序,后将相邻两个按上式子来比较后求得(p/q)。
结果样例错了,后来重推了一遍式子,发现好像有点问题。
最后只好交了个暴力。
赛后发现自己推的没有问题。。。
但同学说排序后相邻两个要按照暴力的方法来比较接近程度。。。
我该成那样后,果然(AC)了。。。
但我觉得这样子打也没有错,想知道为什么。
经过一番推式子:
[abs((y1-y2)/(x1-x2)-P/Q)
]
[abs((Q(y1-y2)-P(x1-x2))/Q(x1-x2))
]
然后发现是通分后将除数去掉才变成上面的式子,但比较大小时不能讲被除数去掉。。。
好吧,我认栽了。
Code
(用暴力方法判断)
#include <cstdio>
#include <algorithm>
#define N 200010
#define db double
#define ll long long
#define mem(x, a) memset(x, a, sizeof x)
#define fo(x, a, b) for (int x = a; x <= b; x++)
#define fd(x, a, b) for (int x = a; x >= b; x--)
using namespace std;
struct node{int x, y; ll num;}a[N];
int n, P, Q, ans1 = 2e9, ans2 = 1;
ll ans = 2ll * 1e9 * 1e9;
inline int read()
{
int x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x;
}
inline bool cmp(node x, node y) {return x.num < y.num;}
db Abs(db x) {return x < 0.0 ? -x : x;}
db slope(node x, node y) {return (db)(y.y - x.y) / (y.x - x.x);}
int gcd(int x, int y) {return ! y ? x : gcd(y, x % y);}
int main()
{
freopen("slope.in", "r", stdin);
freopen("slope.out", "w", stdout);
n = read(), P = read(), Q = read();
fo(i, 1, n)
{
a[i].x = read(), a[i].y = read();
a[i].num = (ll)a[i].y * Q - (ll)P * a[i].x;
}
sort(a + 1, a + n + 1, cmp);
fo(i, 1, n - 1)
{
db x = Abs(slope(a[i], a[i + 1]) - (db)P / Q), y = Abs((db)ans1 / ans2 - (db)P / Q);
if (x < y || (x == y && slope(a[i], a[i + 1]) < (db)ans1 / ans2))
ans1 = abs(a[i].y - a[i + 1].y), ans2 = abs(a[i].x - a[i + 1].x);
}
int gd = gcd(ans1, ans2);
printf("%d/%d
", ans1 / gd, ans2 / gd);
return 0;
}
(用推的式子比较大小判断)
#include <cstdio>
#include <algorithm>
#define N 200010
#define db double
#define ll long long
#define mem(x, a) memset(x, a, sizeof x)
#define fo(x, a, b) for (int x = a; x <= b; x++)
#define fd(x, a, b) for (int x = a; x >= b; x--)
using namespace std;
struct node{int x, y; ll num;}a[N];
int n, P, Q, ans1 = 2e9, ans2 = 1;
db ans = 1.0 * 2e9;
inline int read()
{
int x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x;
}
inline bool cmp(node x, node y) {return x.num < y.num;}
db slope(node x, node y) {return (db)(y.y - x.y) / (y.x - x.x);}
db Abs(db x) {return x < 0.0 ? -x : x;}
int gcd(int x, int y) {return ! y ? x : gcd(y, x % y);}
int main()
{
freopen("slope.in", "r", stdin);
freopen("slope.out", "w", stdout);
n = read(), P = read(), Q = read();
fo(i, 1, n)
{
a[i].x = read(), a[i].y = read();
a[i].num = (ll)a[i].y * Q - (ll)P * a[i].x;
}
sort(a + 1, a + n + 1, cmp);
fo(i, 1, n - 1)
{
db t = Abs((db)(a[i + 1].num - a[i].num) / ((ll)Q * (a[i + 1].x - a[i].x)));
if (t < ans || (t == ans && slope(a[i + 1], a[i]) < (db)ans1 / ans2))
ans = t, ans1 = abs(a[i + 1].y - a[i].y), ans2 = abs(a[i + 1].x - a[i].x);
}
int gd = gcd(ans1, ans2);
printf("%d/%d
", ans1 / gd, ans2 / gd);
return 0;
}