1. 程式人生 > >算法學習——枚舉之基於素數的代數和

算法學習——枚舉之基於素數的代數和

++ orm 圖片 算法實現 只需要 ble src 每次 void

算法描述

基於素數的代數和

s(n) = (1/3)-(3/5)-(5/7)+(7/9)+...+(2n-1)/(2n+1)

分子與分母中有且只有一個素數時符號取+ 分子與分母都不是素數或者都是素數,則前面的符號取-

1.求s(2016)

2.設1<=n<=2016,求當n為多大時,s(n)最大

3.設1<=n<=2016 求當n為多大時,s(n)最接近0

算法思路

  1. 設置一個二維數組存放數值

    a[i][1]存放2i+1

    a[i][0]存放0或1

    如果2i+1是素數,則存放0,不為素數,則存放1

    比如a[3][1]=7 a[3][0]=1

  2. 當分子與分母只有一個是素數的時候,a[i][0]+a[i+1][0]=1

    ,取+,不是的話,則取-。以此為條件,可以計算s(n)的值

  3. 求最大值,我們只需要在每次s(n)加或減之後進行一次判斷,若s大於Max,則交換數值,第k項可以由公式a[i][0]=2i-1求得i,也就是k = (a[i][0]+1)/2

  4. 求最接近0的數值,需要判斷,絕對值是否為最小,求絕對值可以使用Math.abs(double s)方法

算法實現

    Scanner scnner = new Scanner(System.in);
    int n = scnner.nextInt();
    scnner.close();
    int[][] a = new int[2*n+1][2];
    for(int j=0,i=1;i<=2*n+1;i=i+2,j++){
         if(panduan(i)){
            a[j][0]=1; 
        }else{
            a[j][0]=0; //代表i是否為素數,0不是素數,1則是素數
        }
        a[j][1] = i; //
        
    }
    double s =0;
    int k1=1,k2=1;//第k項
    double max =0,min=1;//這裏min最小可以取1,或者取大於1的數字,求得最接近0的k項也是同樣的
    double s2=0; //存放最接近0的數值
    double temp=0;//一個暫時存放數值的變量
    for(int i=0;i<n;i++){
        if(a[i][1]==1){
            temp = (double)a[i][1]/a[i+1][1];
            s =s+ temp;
        }else if(a[i][0]+a[i+1][0]==1){
            temp = (double)a[i][1]/a[i+1][1];
            s = s +temp;
        }else{
             temp = (double)a[i][1]/a[i+1][1];
            s = s -temp;
        }
        if(s>max){
            max =s;
            k1 = (a[i+1][1]-1)/2;
        }
        if(Math.abs(s)<min){
            min =Math.abs(s);
            s2 = s;
            k2 = (a[i+1][1]-1)/2;
        }
    }
    DecimalFormat df = new DecimalFormat("0.00000");//保留5位小數
    System.out.println(df.format(s));
    Max(max, k1);
    Min(s2,k2);
    
    
    private static void Min(double min, int k2) {
        System.out.println("n為"+k2+"s最接近0");
        DecimalFormat df = new DecimalFormat("0.00000");//保留5位小數
        System.out.println(df.format(min));
    }
    private static void Max(double s,int i) {
        System.out.println("n為"+i+"s最大");
        DecimalFormat df = new DecimalFormat("0.00000");//保留5位小數
        System.out.println(df.format(s));
    }
    /**
     * 
     * @param a
     * @return 判斷a是否為素數
     */
    public static boolean panduan(int a){
            int s = (int)Math.sqrt(a);
                for(int i=2;i<=s;i++){
                    if(a%i==0){
                        return false;
                    }
                }
                return true;
            
    }

結果

技術分享圖片

算法學習——枚舉之基於素數的代數和