小红的循环小数
众所周知,所有的无限循环小数都可以写成分数的形式
小红想让你判断循环节长度为k的无限循环小数的分母是否可能是p。你能帮帮她吗?
共有q次询问。
输入描述
第一行输入一个正整数
q
q
q,代表询问次数。
接下来的
q
q
q行,每行输入两个正整数k,p,代表一次询问。
1
≤
q
≤
1
0
5
1\leq q \leq 10^5
1≤q≤105
1
≤
k
,
p
≤
1
0
9
1\leq k,p \leq 10^9
1≤k,p≤109
输出描述
输出
q
q
q行,如果存在一个分子
q
q
q,满足
q
/
p
q/p
q/p为循环节长度为k的无限循环小数,则输出"Yes"。否则输出"No"。
输入示例1
5
1 6
2 4
3 37
100000 3
2 37
输出示例1
Yes
No
Yes
Yes
No
说明
第一组询问,1/6=0.166666……,循环节长度为 1。
第二组询问,显然分母为 4 的小数均为有限小数。
第三组询问,8/37=0.216216216216……,循环节长度为 3。
第四组询问,1/3=0.3333……,显然长度 100000 也是它的循环节长度
💖 思路
👨🏫 参考地址
② 单位分数 1/m,若分母 m 都为
1
0
n
−
1
10^n-1
10n−1,则化成小数后的结果如下
1 9 = 0.1111111 … … \frac{1}{9} = 0.1111111…… 91=0.1111111……
1 99 = 0.010101 … … \frac{1}{99} = 0.010101…… 991=0.010101……
1 999 = 0.001001001 … … \frac{1}{999} = 0.001001001…… 9991=0.001001001……
这种小数叫做单位无限循环小数
0.251251251
…
…
=
251
×
0.001001001
…
…
=
251
×
1
999
0.251251251……=251×0.001001001……=251\times \frac{1}{999}
0.251251251……=251×0.001001001……=251×9991
其中右边分数的分母 999 = 1 0 3 − 1 999=10^3-1 999=103−1,即循环节 = 3 = 10的指数
言归正传:题目求是否存在一个分子 x
,在分母为 p
的情况下,结果为无限循环小数 z
的循环节长度为 k
,,假设现在的循环节为 a
。
即有 z = a × 1 1 0 k − 1 = x p z=a×\frac{1}{10^k-1}=\frac{x}{p} z=a×10k−11=px
Tips:分子 x 可以为任意数
即 a 1 0 k − 1 = a × x a p \frac{a}{10^k-1}=\frac{a\times \frac{x}{a}}{p} 10k−1a=pa×ax
Tips
:即
x
a
\frac{x}{a}
ax也可以是任意数(
a
≠
0
a\neq0
a=0)
换而言之 x a = p 1 0 k − 1 \frac{x}{a} = \frac{p}{10^k-1} ax=10k−1p
③ 上结论:分母 p
转化为
1
0
k
−
1
10^k-1
10k−1 的形式
- p 的质因数中不含 2 或 5 以外的质数 :有限小数
- p 的质因数中不含 2 或 5 两种:则必有一个 p n = 1 0 k − 1 p^n=10^k-1 pn=10k−1
- 质因数中既有2或5,又有其它质因数,可通分为 ( 1 0 n − 1 ) × 1 0 m (10^n-1)\times10^m (10n−1)×10m,此时可转化为无限循环小数,再移动m位小数点(通常称为“混循环”)
💖 解题步骤
- 分母的质因数只含 2 或 5:有限小数
- 否则:
-
1
0
k
−
1
10^k-1
10k−1 % p == 0,存在分子
x
可以通分成 a - else 不存在
-
1
0
k
−
1
10^k-1
10k−1 % p == 0,存在分子
💖 AC code
import java.util.*;
class Main
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 0; i < n; i++)
{
System.out.println(result(sc.nextInt(), sc.nextInt()) ? "Yes" : "No");
}
}
public static boolean result(int k, int p)
{
while (p % 2 == 0)//消去质因子 2
p /= 2;
while (p % 5 == 0)//消去质因子 5
p /= 5;
if (p == 1)
return false;
return (qpow(10, k, p) - 1) % p == 0;
}
// 快速幂
private static long qpow(int x, int k, int mod)
{
long ans = 1;
while (k != 0)
{
if ((k & 1) != 0)
ans = ans * x % mod;
k >>= 1;
x = x * x % mod;
}
return ans;
}
}