CF983A

题意

给定p,q,b,问p,q是否表示成b进制下的有限小数位

数据范围\(p,q,b<=10^{18}\)

思路

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

把1/q,换成小数形式,例如1/8=0.125,像整数转换进制一样,小数转换进制也是不断地除以基底,而小数的基底

\(b^{-1}\),则0.125转换成二进制如下,0.125除以\(2^{-1}\),变成0.5,0.5除以\(2^{-1}\),变成1,所以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

代码

#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); //取出_g和q的最大公约数,而根据质因数分解定理,最大公约数可以表示成素因子的乘积 
			if(_g == 1) break;//如果最大公约数是1,我们就跳出,防止死循环 , 
			while(q % _g == 0) q /= _g;
		}
		if(q == 1) printf("Finite\n");//如果分母为1,就表明,我可以将一个小数转化成一个b进制数 
		else printf("Infinite\n");
	}
	return 0;
}
posted @ 2020-08-25 09:02  邦的轩辕  阅读(154)  评论(0编辑  收藏  举报