BZOJ2187:fraction

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/oi_Konnyaku/article/details/84929501

Sol

分情况讨论

  1. a b + 1 c d 1 \lfloor\frac{a}{b}\rfloor+1\le \lceil\frac{c}{d}\rceil-1
    直接取 q = 1 , p = a b + 1 q=1,p=\lfloor\frac{a}{b}\rfloor+1
  2. a = 0 a=0
    那么 q > p d c q> \frac{pd}{c}
    直接取 p = 1 , q = d c + 1 p=1,q=\lfloor\frac{d}{c}\rfloor+1
  3. a < b a<b c d c\le d
    那么递归处理 d c < q p < b a \frac{d}{c} < \frac{q}{p} < \frac{b}{a}
  4. a b a\ge b
    那么递归处理 a   m o d   b b < p q a b < c d a b \frac{a~mod~b}{b} < \frac{p}{q}-\lfloor\frac{a}{b}\rfloor < \frac{c}{d}-\lfloor\frac{a}{b}\rfloor

形式上类似于欧几里得算法,把 ( a , b ) (a,b) 转化成 ( a   m o d   b , b ) (a~mod~b,b) 可能就是是类欧几里得算法的精髓

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;

inline ll Gcd(ll x, ll y) {
	if (!x || !y) return x | y;
	return !y ? x : Gcd(y, x % y);
}

inline void Solve(ll a, ll b, ll c, ll d, ll &x, ll &y) {
	register ll g = Gcd(a, b), nx, ny;
	a /= g, b /= g, g = Gcd(c, d), c /= g, d /= g;
	nx = a / b + 1, ny = c / d + (c % d > 0) - 1;
	if (nx <= ny) x = nx, y = 1;
	else if (!a) x = 1, y = d / c + 1;
	else if (a < b && c <= d) Solve(d, c, b, a, y, x);
	else Solve(a % b, b, c - d * (a / b), d, x, y), x += y * (a / b);
}

ll a, b, c, d, x, y;

int main() {
	while (scanf("%lld%lld%lld%lld", &a, &b, &c, &d) != EOF) Solve(a, b, c, d, x, y), printf("%lld/%lld\n", x, y);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/oi_Konnyaku/article/details/84929501
今日推荐