题目描述:
You are given several queries. Each query consists of three integers pp, qq and bb. You need to answer whether the result of p/qp/q in notation with base bb is a finite fraction.
A fraction in notation with base bb is finite if it contains finite number of numerals after the decimal point. It is also possible that a fraction has zero numerals after the decimal point.
The first line contains a single integer nn (1≤n≤1051≤n≤105) — the number of queries.
Next nn lines contain queries, one per line. Each line contains three integers pp, qq, and bb (0≤p≤10180≤p≤1018, 1≤q≤10181≤q≤1018, 2≤b≤10182≤b≤1018). All numbers are given in notation with base 1010.
For each question, in a separate line, print Finite if the fraction is finite and Infinite otherwise.
2 6 12 10 4 3 10
Finite Infinite
4 1 1 2 9 36 2 4 12 3 3 5 4
Finite Finite Finite Infinite
612=12=0,510612=12=0,510
43=1,(3)1043=1,(3)10
936=14=0,012936=14=0,012
412=13=0,13
题意大致是:给你一个十进制分数(分子p,分母q)让你把这个分数转换成b进制,看他在b进制下是有限小数还是无限小数。
于是我就百度了一下判断进制转换,在bd知道里看到这样一个回答:
带有小数部分的不同进制转化,本质上是通分的过程。
比如0.375 = 3/8转成二进制,最大分母就是2^3,而分子只要是整数就行了。
因此,将一个k进制的小数比如0.25631先转换成2/k + 5/(k^2) + ... + 1/(k^5)然后通分计算成M/(k^5),再化成最简分数(分子分母互素)比如a/b如果要将这个数转成r进制,则要求b是r的幂。否则就不能转化成有限小数形式。
但是这里好像是错的= =?, 正确的应该是:
a/b能化成有限小数的必要和充分条件是在分母内只含有r或只含有r的因数。
为什么?类比十进制中如何判断分数是否为有限/无限小数:
如果一个分数无法将其分母写成10^n,那就无法写出其有限小数的形式。这样,当一个分数经过约分,化成最简分数后,如果分母质因数分解式是:2^m*5^n(m、n是含零自然数)的形式,当m=n时,那分母就是10^n了,这就很显然了。
这里又找到一篇关于进制转换的数学论文,里面有经过证明的定理可以直接使用:数学论文:《任意进制的循环小数》(蒟蒻看不懂啊orz)
显然:此题先p,q化简coprime,然后p/=gcd(p, b)进行约分,看b是否包含p的全部因子即可。
上代码:
#include<bits/stdc++.h> #define ll long long using namespace std; #define FOR(i,n) for(int i=0; i<n; i++) ll gcd(ll a, ll b) {return b ? gcd(b, a%b) : a;} int main() { ios::sync_with_stdio(false); int t;cin>>t; while(t--) { ll p, q, r; cin>>p>>q>>r; if(p==0) {puts("Finite"); continue;} ll t=gcd(p, q); q/=t; p/=t; while(q>1&&r>1) { r = gcd(r, q); q /= r; } if(q==1) {puts("Finite"); continue;} else {puts("Infinite"); continue;} } return 0; }