CF1720A 题解

前言

题目传送门!

更好的阅读体验?

和官方题解稍有不一样。貌似代码更好理解?

思路

我们假设 \(a\) 乘上 \(x\)\(b\) 乘上 \(y\),就能相等,即 \(\dfrac{ax}{by} = \dfrac{c}{d}\)

化简:\(axd = byc\)。也就是 \(x \cdot(ad) = y \cdot (bc)\)

也就是 \(\dfrac{x}{y} = \dfrac{bc}{ad}\)。这个就是比值。

假设 \(k = \gcd(bc, ad)\),我们可以得到 \(x : y = \dfrac{bc}{k} : \dfrac{ad}{k}\)

不过这样不严谨,因为 \(k = 0\) 时是不成立的。我们特判一下 \(k = 0\),结果显然为 \(0\)

\(k \ne 0\) 的情况下,由于 \(k\) 是最大公因数,故 \(x\)\(y\) 可以直接取 \(\dfrac{bc}{k}\)\(\dfrac{ad}{k}\)

由于 \(x = 1\) 相当于分子没有操作,因此不记入操作次数内。\(y = 1\) 同理。

进一步地,\(ans = [x \ne 1] + [y \ne 1]\)

至此本题就做完了。时间复杂度为 \(\gcd\) 的复杂度。

完整代码

#include <iostream>
#include <cstdio>
using namespace std;
int read()
{
	char op = getchar(); int x = 0, f = 1;
	while (op < 48 || op > 57) {if (op == '-') f = -1; op = getchar();}
	while (48 <= op && op <= 57) x = (x << 1) + (x << 3) + (op ^ 48), op = getchar();
	return x * f;
}
void write(int x)
{
	if (x < 0) putchar('-'), x = -x;
	if (x > 9) write(x / 10);
	putchar(x % 10 + 48);
}
LL gcd(LL x, LL y) {return y == 0 ? x : gcd(y, x%y);}
void solve()
{
	int a = read(), b = read(), c = read(), d = read();
	LL t1 = 1ll * a * d, t2 = 1ll * b * c, g = gcd(t1, t2); //注意 LL
	if (g == 0) {putchar('0'), endl; return;}  //特判
	t1 /= g, t2 /= g; //如上分析的化简步骤
	write((t1 != 0) + (t2 != 0)), putchar('\n');
}
int main()
{
	int T = read();
	while (T--) solve();
	return 0;
}

希望能帮助到大家!

首发:2022-08-19 09:53:11

posted @ 2022-08-27 13:14  liangbowen  阅读(14)  评论(0编辑  收藏  举报