题意:
给定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;
}
继续加油~