Reciprocal cycles

https://projecteuler.net/problem=26

Reciprocal cycles

Problem 26

A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:

1/20.5
1/30.(3)
1/40.25
1/50.2
1/60.1(6)
1/70.(142857)
1/80.125
1/90.(1)
1/100.1

Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.

Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.

因为分母部分保持不变,所以只要分子部分一旦重复出现,循环小数的数量就确定下来了。而分子部分其实就是对分母取余剩下的那部分。 可以测试一下1/7即可。

因为取余的值不会大于分母,所以计算量也不会大于分母。

当然,有一个公式可以算出素数的循环小数的位数,用起来更简单一点,不过1000个也就没有必要了。

当然除了像下面这样蛮算,还可以将数拆分下来,求所有的因子,如:1/21 = 1/3  * 1/ 7他的循环小数位数 就是 1 * 6.依次类推,也挺简单的。

def ReciprocalCycles():
    #循环小数数量集合
    result = 0
    maxNum = 0
    for i in range(1,1000):
        #找到每一个值的循环小数数量
        tmp = CountCycle(i)
        if maxNum < tmp:
            maxNum = tmp
            result = i
    return result

def CountCycle(num):
    #余数的字典,记录每一个余数所在的位置
    ModDict={}
    #把1初始化进去
    ModDict[1]=0
    #记录下一个余数所在位置
    index=1
    #下一个除数是1 * 10
    Numerator = 10
    #求取第一个真正的余数
    modNum = Numerator % num
    #如果余数为零,或者余数之前出现过,则退出,否则一直进行
    while modNum != 0 and modNum not in ModDict:
        #将余数和其位置放到字典里面
        ModDict[modNum] = index
        #除数初始化
        Numerator = modNum * 10
        #求余数
        modNum = Numerator % num
        #更新余数的下一个位置
        index += 1
    #如果能除尽,则不是循环小数
    if modNum == 0:
        return 0
    #返回两个相同余数的位置差,就是循环小数的数量
    return index - ModDict[modNum]

print(ReciprocalCycles())
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值