题目
正整数k的倒数1/k,写为10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数,假如存在多个最优的答案,输出所有答案中最大的那个数。
1/6= 0.1(6) 循环节长度为1
1/7= 0.(142857) 循环节长度为6
1/9= 0.(1) 循环节长度为1
收起
输入
输入n(10 <= n <= 1000)
输出
输出<=n的数中倒数循环节长度最长的那个数
输入样例
10
输出样例
7
解题思路:对于,我们可以想象除法的过程。很明显是每一步除法之后的余数乘10得到的数再次开始做除法。因此为了让小数部分循环,那么只要找到除数部分的循环即可。也就是说,找到最小的k,直接暴力。对于i与10不互素的情况,可以先化简成互素的情况,对于某个分数来说,循环节只与分母有关,因此可以直接用的结果,对于i与10互素的情况下根据欧拉定理必定存在,因此枚举,找到最小的k使得,k即为循环节。暴力枚举即可。
代码:
#include<bits/stdc++.h>
using namespace std;
int oular(int n){
int res = n;
int len = sqrt(n);
for(int i = 2;i <= len;++i)
if(n % i == 0){
while(n % i == 0) n /= i;
res = res / (i - 1) * i;
}
if(n > 1) res = res / (n - 1) * n;
return res;
}
int main(){
int n,Max = 0,ans = 1;
scanf("%d",&n);
for(int i = 2;i <= n;++i){
int t = oular(i),cnt = 0,tmp = 1;
for(int j = 1;j <= t;++j){
tmp = tmp * 10 % i;
if(tmp == 1){
cnt = j;
break;
}
}
// cout<<i<<':'<<cnt<<endl;
if(cnt > Max){
Max = cnt;
ans = i;
}
}
printf("%d\n",ans);
return 0;
}