欧拉工程第26题:Reciprocal cycles

题目链接: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();//983
        Date endTime=new Date();
        long Time = endTime.getTime()-beginTime.getTime();
        System.out.println("Time:"+Time/1000+"秒"+Time%1000+"毫秒");
        }
}

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

你可能感兴趣的:(欧拉工程,费马小定理)