CodeForce Round #483 C.Finite or not?(數論gcd)

題目鏈接

題目大意是:

給你三個整數,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;
} 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章