Codeforces-984C - Finite or not?(數論)

題意:

給定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;
}

繼續加油~

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