题目描述:给你一个p/q,让你求在b进制下,这个小数是不是有限小数。
思路:
先来膜拜一个大神的博客,如何求小数的二进制表达,(感谢博主肘子zhouzi)。然后小数的其他进制表达也一样。
而分数的转化,比如1/6转化成3进制,看图 ↓ 。
其实就是将1/6不断乘以3,然后丢掉整数部分,如果我们不看丢掉整数部分这个环节,就是把1/6不断乘以3看看最后能不能整除就好了,如果有限的话,肯定会得到((b)^n))%q=0,b的某一次幂可以整除q,就代表是有限。(感谢薛佬帮我理解!!)
那么一个朴素的想法,就是,n从1一直加上去,找到一个可以整除的,但问题是 证有不证无,我们无法保证n到几退出循环,所以要改进思路。
其实b^n整除q的过程,其实就是b^n的因子和q的因子不断约分的过程,如果约分到最后,q还剩下一个b中没有的因数,则说明无法整除。 那就是每一次都用q除去gcd(q,b),这样消耗q消耗到最后,判断得到的数是不是1,是1则代表可以整除,不是1则代表 用b没法约分q了,不能整除。思路就是这样
但代码中有不少细节要注意。
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
if(a%b==0)return b;
else return gcd(b,a%b);
} //辗转相除法求两个数的最大公因数
int main()
{
int n;
cin>>n;
while(n--)
{
ll p,q,b;
//cin>>p>>q>>b; 超时
scanf("%I64d%I64d%I64d",&p,&q,&b); //cf读入longlong类型只能用 I64%
if(p==0)
{
printf("Finite
");
}else
{
q/=gcd(p,q);//约分
ll g;
while(g=gcd(q,b),g!=1)
{
while(q%g==0)//由于可能出现q=10000000000 g=2的情况 这样子多次调用gcd会浪费时间 所以在这里优化一下
q=q/g;
}
if(q==1){ // q最后如果为 1 则用若干个b把q消耗掉了 即b的若干次方 可以整除 q
printf("Finite
");
}else{
printf("Infinite
");
}
}
}
}
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