欧拉工程第51题:Prime digit replacements

题目链接

题目:

通过置换*3的第一位得到的9个数中,有六个是质数:13,23,43,53,73和83。

通过用同样的数字置换56**3的第三位和第四位,这个五位数是第一个能够得到七个质数的数字,得到的质数是:56003, 56113, 56333, 56443, 56663, 56773, 和 56993。因此其中最小的56003就是具有这个性质的最小的质数。

找出最小的质数,通过用同样的数字置换其中的一部分(不一定是相邻的部分),能够得到八个质数。

解题思想:

这个题目是很难的

你首先要找到可能替换匹配的模板

唯一的信息就是这个数是质数,除1和本身外不能别其他整数整除。

这个数不能被三整除,(根据不能被三整除,找出这个数的模板,这个是在网上看到的),这个数一定不能被三整除。

假设这八个质数是5位数

假设这个5位数各位数字是:a、b、c、d、e

(a+b+c+d+e)%3只能取1,2

若是只替换其中1位:

e

下面对(a+b+c+d)%3 的取值分类讨论

1.(a+b+c+d)%3==0,e%3==1,2.e 取值:1,2,4,7,8,最多只能有5个这样的质数

2.(a+b+c+d)%3==1 ,e%3==0,1 e  取值:0,1,3,4,6,7,9,不合适

3..(a+b+c+d)%3==2 ,e %3==0,2 .e 取值:0,3,5,6,8,9,不合适

若是只替换其中2位:

d == e

下面对(a+b+c)%3 的取值分类讨论

1.(a+b+c)%3==0,2e%3==1,2.e 取值:1,2,4,5,7,8,不合适

2.(a+b+c)%3==1 ,2e%3==0,1 e  取值:0,2,3,5,6,8,9,不合适

3..(a+b+c)%3==2 ,2e %3==0,2 .e 取值:0,1,3,4,6,7,9,不合适

若是只替换其中3位:

c==d == e

下面对(a+b)%3 的取值分类讨论

1.(a+b)%3==0,3e%3==1,2.无值可取,不合适

2.(a+b)%3==1 ,3e%3==0,1 e  取值:0,1,2,3,4,5,6,7,8,9,合适

3..(a+b)%3==2 ,3e %3==0,2 .e 取值:0,1,2,3,4,5,6,7,8,9,合适

根据上面可以发现规律:

我们考虑问题的重点是替换部分是几位的数字,与这个数是几位数字关系不大。

替换部分是三位数:替换部分可以是:000,111,222,333,444,555,666,777,888,999

原始数可能是四位数或者是五位数。

替换几个数字我们知道了

具体替换到哪几位还不知道。。。

这个时候就只能暴力了。。。

如果是五位数:

替换模型可能是:

//a是要换的 ,相同数据,b是保持不变的
        String[] digits5={"baaab",
                          "abaab",
                          "aabab",
                          "aaabb"};

a不能在最后一位,是的话就不够8个质数了。

如果是六位数:

替换模型可能是:

String[] digits6={"bbaaab",
        "babaab",
         "baabab",
         "baaabb",
         "abbaab",
        "ababab",
        "abaabb",
        "aabbab",
         "aababb",
         "aaabbb"};

下面就纯暴力破解了

根据模板产生9个数

判断这九个数中是否有8个质数

有就ok

运行输出结果:

[109, 111109, 222109, 444109, 555109, 666109, 777109, 888109]
[121313, 222323, 323333, 424343, 525353, 626363, 828383, 929393]
[40609, 141619, 242629, 343639, 444649, 646669, 747679, 949699]
[857, 111857, 222857, 333857, 555857, 666857, 777857, 888857]

输入109不对,输入121313,ok这里是要求的是数长度是6

java代码:

package projecteuler51to60;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

class level51{
    void solve0(){
        //a是要换的 ,相同数据,b是保持不变的
        String[] digits5={"baaab",
                          "abaab",
                          "aabab",
                             "aaabb"};
        String[] digits6={"bbaaab",
                          "babaab",
                          "baabab",
                          "baaabb",

                       "abbaab",
                       "ababab",
                       "abaabb",

                       "aabbab",
                       "aababb",

                       "aaabbb"};
        TreeSet<String> ts = new TreeSet<String>();

        for(int i=0;i<=9;i++){
            for(int j=0;j<=9;j++){
                for(int k=0;k<digits5.length;k++){
                ts=Combination(i, j, 0, digits5[k], true);
                if(isPrimeSet(ts))
                System.out.println(i+" "+j+" "+ts+" "+digits5[k]);
                }

            }
        }
        TreeSet<String> ts2 = new TreeSet<String>();
        for(int i=0;i<=9;i++){
            for(int j=0;j<=9;j++){
                for(int m=0;m<=9;m++){
                for(int k=0;k<digits6.length;k++){
                ts2=Combination(i, j, m, digits6[k], false);
                if(isPrimeSet(ts2)){
//                System.out.println(i+" "+j+" "+ts2+" "+digits6[k]);
                System.out.println(getPrimeSet(ts2));//121313

                }
                }
                }
            }
        }

    }
    TreeSet<Integer> getPrimeSet(TreeSet<String> ts){
        Iterator<String> it=ts.iterator();
        TreeSet<Integer> tset = new TreeSet<Integer>();
        while(it.hasNext()){
            int prime=Integer.parseInt(it.next());//强制类型转换
            if(isPrime(prime)){
                tset.add(prime);
            }
        }

        return tset;

    }

    boolean isPrimeSet(TreeSet<String> ts){
        Iterator<String> it=ts.iterator();
        int flag=0;
        while(it.hasNext()){
            int prime=Integer.parseInt(it.next());//强制类型转换
            if(isPrime(prime)){
                flag+=1;
            }
        }
        if(flag>=8)
            return true;
        return false;

    }

    TreeSet<String> Combination(int A,int B,int C,String pattern,boolean flag){
        //第一个1用a代替,第二个1以b代替,第三个1用c代替

        TreeSet<String> TSet= new TreeSet<String>();
        if(flag==true){// 5位数
            for(int i=0;i<=9;i++){
                String combStr=pattern.replaceFirst("b", A+"");
                combStr=combStr.replaceFirst("b", B+"");
                combStr=combStr.replace("a", i+"");
                TSet.add(combStr);
            }
        }else if(flag==false){// 6位数
            for(int i=0;i<=9;i++){
                String combStr=pattern.replaceFirst("b", A+"");
                combStr=combStr.replaceFirst("b", B+"");
                combStr=combStr.replaceFirst("b", C+"");
                combStr=combStr.replace("a", i+"");
                TSet.add(combStr);

            }
        }
        return TSet;
    }

    boolean isPrime(int num){
        if(num==2||num==3 ||num==5||num==7) return true;
        if(num<2 || num%2==00) return false;
        for(int i=3;i<=Math.sqrt(num);i++)
            if(num%i==0)
                return false;
        return true;
    }

}
public class Problem51 {

    public static void main(String[] args){
        long begin= System.currentTimeMillis();
        new level51().solve0();
        long end = System.currentTimeMillis();
        long Time = end - begin;
        System.out.println("Time:"+Time/1000+"s"+Time%1000+"ms");
    }

}
时间: 2024-10-27 00:02:00

欧拉工程第51题:Prime digit replacements的相关文章

欧拉工程第70题:Totient permutation

题目链接 和上面几题差不多的 Euler's Totient function, φ(n) [sometimes called the phi function]:小于等于n的数并且和n是互质的数的个数 存在这样的数:N的欧拉数φ(n),是N的一个排列 例如:φ(87109)=79180 求在1---10^7中n/φ(n) 取到最小的 n 是多少? 这里的是p是n的素因子,当素因子有相同的时候只取一个 任意一个正整数都能分解成若干个素数乘积的形式 直接利用上题的phi函数就可以求解 这个是跑的最

欧拉工程第63题:Powerful digit counts

题目链接 这个题目有点坑: 先说自己的思路<虽然走不通> 根据题意可知道: a的b次方 除以 最小的b位数(如:10,100,1000) 的商 在 1--9之间,则:a的b次方就是符合题意的 然后就根据这个遍历 先找到第一个数符合条件的数firstnum 再找到第一个符合条件之后的第一个不满足条件的数nextnum 则:这中间有 nextnum - firstnum个数 当b也就是次方数大于18的时候,Long都溢出了 此时:有38个数

欧拉工程第56题:Powerful digit sum

题目链接   Java程序 package projecteuler51to60; import java.math.BigInteger; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; class level56{ void solve0(){ int maxsum=0; for(int a=2;a<100;a++){ for(int b=2;b<100;b++){ BigInteger

欧拉工程第60题:Prime pair sets

题目链接 五个数,任意两个数的任意链接后的数还是质数 满足这个条件的最小五个数的和是多少? 结果:26033 纯暴力破解: package projecteuler51to60; import java.util.ArrayList; import java.util.List; import java.util.TreeSet; class level60{ void solve1(){ List<Integer> primes = new ArrayList<>(); int

欧拉工程第67题:Maximum path sum II

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. 37 42 4 68 5 9 3 That is, 3 + 7 + 4 + 9 = 23. Find the maximum total from top to bottom in triangle.txt (right c

欧拉工程第66题:Diophantine equation

题目链接 脑补知识:佩尔方差 上面说的貌似很明白,最小的i,对应最小的解 然而我理解成,一个循环的解了,然后就是搞不对,后来,仔细看+手工推导发现了问题.i从0开始变量,知道第一个满足等式的解就是最小解. 问题转化为求根号n的连分数问题,分子就是x,分母就是y 要求的分子,分母,问题又转化为:根号n的连分数表示,对,求出其连分数表示就OK了 先求出a的序列是什么? 第64题,就是求a的序列的. a求出来了,要求出分子分母的表达式. 第65题,就是已经知道了a的序列,求分子,当然也可以求分母的 分

欧拉工程第65题:Convergents of e

题目链接 现在做这个题目真是千万只草泥马在心中路过 这个与上面一题差不多 这个题目是求e的第100个分数表达式中分子的各位数之和 What is most surprising is that the important mathematical constant,e = [2; 1,2,1, 1,4,1, 1,6,1 , ... , 1,2k,1, ...]. The first ten terms in the sequence of convergents for e are: 2, 3,

欧拉工程第71题:Ordered fractions

题目链接:https://projecteuler.net/problem=71 If n<d and HCF(n,d)=1, it is called a reduced proper fraction. n/d 真分数升序排序后,离 3/7最近的数,d<=1000000 Java程序: public class P71{ void run(){ calculate(); } void calculate(){ int max_n = 1000000; long a = 3; long b

欧拉工程第73题:Counting fractions in a range

题目链接:https://projecteuler.net/problem=73 n/d的真分数 ,当d<=12000时 在 1/3 and 1/2 之间的有多少个 public class P73{ void run(){ FareySequences(); } void FareySequences(){ int limit = 12000; int a = 1; int b = 3; int c = 4000; int d = 11999; int count=0; while(!(c==