題目大意是:
給你三個整數,p,q,b。其中p/q是個分數。該題目要求你給出p/q在b進制下是否是個無限小數。
解題思路:
首先我們需要知道小數轉化爲二進制。假定有分數a/b(a<b),要將它轉化爲k進制。我們需要取a * k / b爲第
一位。然後讓a = a * k % b.重複以上步驟,直到a* k % b == 0;
a * k % b 一直不等於0那麼就說明這個分數是無限小數。
如果判斷 a * k % b 一直不等於0在代碼層面是可行的,但是時間複雜度複雜度會比較高,而且從邏輯上說
也比較麻煩。
我們可以換一種思路,我們只要判斷a * k % b 在小數轉化爲二進制這個過程是否能等於0即可。
具體該題思路就很清晰了:
我們可以先將p/q化簡得到化簡後的p/q.如果1/q是無限小數,那麼他乘上p後也是個無限小數。所以我們發
現一個分數在b進制下是否是無限小數只跟這個分數化簡後的分母和b有關。
根據前面的推論,我們只需判斷是否存在一個i使得b ^ i % q == 0 即可。、
很容易看出存在b ^ i % q == 0的充分條件是b必須包含q的所有質因子。
如當b = 1386,q = 252時,b的質因子有2 * 3 * 3 * 7 * 11。 q的質因子有 2 * 2 * 3 * 3 * 7.
此時我們就可以說b 包含q的所有質因子(注意此時說的包含是指種類包含)。
代碼如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define mmset(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b,a % b);
}
/*
2
6 12 10
4 3 10
outputCopy
Finite
Infinite
inputCopy
4
1 1 2
9 36 2
4 12 3
3 5 4
outputCopy
Finite
Finite
Finite
Infinite
*/
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ll p,q,b;
scanf("%lld %lld %lld",&p,&q,&b);
ll g = gcd(q,p);
q /= g, p /= g;
if(p == 0 || q == 1)
{
printf("Finite\n") ;
}
else
{
int g;
while(q != 1&&b != 1)
{
b = gcd(q,b);
q /= b;
}
if(q == 1)
{
printf("Finite\n");
}
else
{
printf("Infinite\n");
}
}
}
return 0;
}