二、最长的循环节

1035 最长的循环节

10进制的小数如果为无限循环小数,则存在一个循环节,求<=n的数中,倒数循环节长度最长的那个数,假如存在多个最优的答案,输出所有答案中最大的那个数。
1/6= 0.1(6) 循环节长度为11/7= 0.(142857) 循环节长度为61/9= 0.(1) 循环节长度为1

循环小数的性质:

如果循环小数的每个循环节长度为偶数,(记为2K),那么循环节中第i(1<=i<=k)个数字 + 第(i+k)个数字之和为9;

如果p是质数,并且d是1/p的循环节的位数,则d可以整除p−1;

如果1≤b<a, a没有2或者5的质因数,并且a与b互质,那么b/a的循环节位数等于:min{e∈N:10^e≡1(mod a)} 。

如果1≤b<a, a没有2或者5的质因数,并且a与b互质,那么b/a的循环节位数必整除ψ(a)(即a的欧拉函数)。

如果n,m≥3 2和5都不整除mn,并且n与m是互质的正整数,则1/mn的循环位数是1/n与1/m循环小数位数的最小公倍数;

…………,其他定理可以参考论文。

以下是学习笔记:

上面说到的第三条性质主要是用于求一个分数的循环节的长度,如果符合没有2或者5的质因数,就利用上面公式求解,如果不符合就将2或者5的质因子提出然后利用上面的定理。

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <vector>

using namespace std;
const int Maxn = 1008;
struct table{
    int max_id;
    int max_val;
}note[Maxn];
int gcd(int a){
    int i=1;
    int p = 0;
    while(1){
        i = i*10%a;
        p++;
        if(i==1){
            return p;
        }
    }
}
int jian(int a){
    while(a%5==0){
        a = a/5;
    }
    while(a%2==0){
        a = a/2;
    }
    return a;
}
int n;
int main(){
    for(int i=0;i<Maxn;i++){
        note[i].max_id = note[i].max_val = 0;
    }
    note[10].max_id = 7;
    note[10].max_val = 6;
    while(~scanf("%d",&n)){
        if(note[n].max_id){
            printf("%d\n",note[n].max_id);
            continue;
        }
        for(int i=11;i<=n;i++){
            if(note[i].max_id!=0)
                continue;
            note[i].max_id = note[i-1].max_id;
            note[i].max_val = note[i-1].max_val;
            if(i%2==0||i%5==0){
                int temp = jian(i);
                if(temp==note[i].max_id){
                    note[i].max_id = temp;
                }
            }
            else{
                int temp = gcd(i);
                if(temp>=note[i].max_val){
                    note[i].max_val = temp;
                    note[i].max_id = i;
                }
            }
        }
        printf("%d\n",note[n].max_id);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值