jzoj 6290. 倾斜的线

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\n", 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\n", ans1 / gd, ans2 / gd);
	return 0;
}
posted @ 2019-08-17 15:27  jz929  阅读(95)  评论(0编辑  收藏  举报