Codeforces-984C - Finite or not?(数论)

版权声明:如有错误请指出,转载请注明出处。 https://blog.csdn.net/yo_bc/article/details/80342521

题意:

给定p,q,b,问p/q能否表示成b进制下的有限小数形式(p,q,b <= 1e18)

思路:

对于约分后的p/q,只需关心1/q是否能在b进制下有限表现即可。

把1/q换成小数形式,例如1/8 = 0.125,像整数转换进制一样,小数转换进制也是不断地除以进制的基,而小数的基是b^-1。则0.125转换为二进制过程如下,0.125(除2^-1)-->余0商0.25(除2^-1)-->余0商0.5(除2^-1)-->余1商0-->停止。所以0.125的二进制形式就是0.001。所以1/q能否能在b进制下有限表现即 是否存在x使 1/q * b^x == 整数(没有小数位)即 是否存在x使q能被b^x整除

其实最终能转化成 q中的所有质因子是否都是b中的质因子。

...

有个性质:

如果p/q是分数的最简形式。

那么p/q能化成有限小数。当且仅当q的质因数分解形式中只有质因子2和5。

(且不能出现其他质因子)

解释:十进制下,p/q(最简形式)在开始进行小数点后的运算时,p相当于不断地*10,实际是在不断地增加10的所有质因子的指数。如果是有限位小数,那么就说明了在某个时刻凑够了q的所有质因子的相应指数个数。因为只是在增加10的质因子,那么也就相应地说明q的所有质因子都是10中的质因子。

所以问题就是 判断约分后的q中的所有质因子是否都是b中的质因子。

...

由于gcd的本质上就是两个数中相同质因子中取指数较小的一个,然后全都乘起来的值。

所以不断用q除以gcd(q, b)直到gcd == 1,最后再判断一下q == 1? 'Fin' : 'Inf'.

优化:q可以除以多次此时的gcd(q, b)。n*log*log会Tle。

...

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll gcd(ll a, ll b) {
	if(b == 0) return a;
	return gcd(b, a%b);
}
int main() {
	ll p, q, b, _g;
	int n; scanf("%d", &n);
	while(n--) {
		scanf("%I64d %I64d %I64d", &p, &q, &b);
		q /= gcd(p, q);
		_g = b;
		while(q != 1) {
			_g = gcd(_g, q);
			if(_g == 1) break;
			while(q % _g == 0) q /= _g;
		}
		if(q == 1) printf("Finite\n");
		else printf("Infinite\n");
	}
	return 0;
}

继续加油~

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页