当前位置: 代码迷 >> 综合 >> 欧拉工程第26题:Reciprocal cycles
  详细解决方案

欧拉工程第26题:Reciprocal cycles

热度:99   发布时间:2023-12-13 07:17:32.0

题目链接:https://projecteuler.net/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/2 = 0.5
1/3 = 0.(3)
1/4 = 0.25
1/5 = 0.2
1/6 = 0.1(6)
1/7 = 0.(142857)
1/8 = 0.125
1/9 = 0.(1)
1/10 = 0.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.
求1000一下,1/d的小数的循环体最长的那个d。
一个字:坑。
思路:
1.根据编程之美上面小数化成分数的思想===>没有实现,也无法实现
2.想想应该与素数有关系,或者求得答案就是一个素数===>下面也就是不知道怎么搞了

网上看别人怎么做的
1.根据编程之美中小数化成分数的思想+素数===>得出答案
2.让10的倍数分别处于这个数,当出现循环的时候,结束,除数就是循环体中的数字
3.看这个数字能让被多少个9整除,比如:99999%d==0,循环体长度就是5

对于1,应用到费马小定理,具体没理解意思。
对于2、3应该是差不多的方法。
给个关于质数的链接:链接,我们这里求得是全循环质数。里面有简短介绍。

2对应的程序:

void solve2(){      int remainder=0;    int max=0;int result=0;for(int d=2;d<1000;d++){ArrayList list=new ArrayList();list.add(new Integer(1));int count=1;int temp=10;while(true){remainder= temp%d;if(list.contains(remainder) || remainder==0){if(count>max){max=count;result=d;}if(d==6){System.out.println(list);System.out.println(count);}break;}else{list.add(new Integer(remainder));temp=remainder*10;count++;}}}System.out.println(result);}

上面程序还是有点小问题的,在输出6的循环体长度的时候是2,然而1/6=0.1(6) ,循环体只有6 没有1,长度是1,程序没有判定小数部分不是循环体的。 但是输出结果没影响。。。。。。。
看到一个这样的定理:
费马小定理,这个其实也就是费马小定理的应用。
对任意的质数,一定存在正整数k使10的k次方除以n的余数是1,这里的k就是1/n,的循环体的长度。这样上面打代码有问题就对了,可以对上面代码进行优化。只对是素数的进行while里面程序运算。
这样看来上面的三个做法应该是一样,只是在判断是有小的差别。

package projecteuler21to30;import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;class level26{
    void solve2(){      int remainder=0;    int max=0;int result=0;for(int d=2;d<1000;d++){ArrayList list=new ArrayList();list.add(new Integer(1));int count=1;int temp=10;while(true){remainder= temp%d;if(list.contains(remainder) || remainder==0){if(count>max){max=count;result=d;}if(d==6){System.out.println(list);System.out.println(count);}break;}else{list.add(new Integer(remainder));temp=remainder*10;count++;}}}System.out.println(result);}void solve1(){      int remainder=0;    int max=0;int result=0;for(int d=2;d<1000;d++){ArrayList list=new ArrayList();list.add(new Integer(1));int count=1;int temp=10;if(isPrime(d)){while(true){remainder= temp%d;if(list.contains(remainder) || remainder==0){if(count>max){max=count;result=d;}if(d==6){System.out.println(list);System.out.println(count);}break;}else{list.add(new Integer(remainder));temp=remainder*10;count++;}}}}System.out.println(result);}boolean isPrime(int num){for(int i=2;i<=Math.sqrt(num);i++){if(num%i==0){return false;}}return true;}
}
public class Problem26 {
    public static void main(String[] args){Date beginTime=new Date();new level26().solve2();//983Date endTime=new Date();long Time = endTime.getTime()-beginTime.getTime();System.out.println("Time:"+Time/1000+"秒"+Time%1000+"毫秒");}
}

增加判断素数的时间能提高10-20ms