算法學習——枚舉之基於素數的代數和
阿新 • • 發佈:2018-09-15
++ 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
算法思路
設置一個二維數組存放數值
a[i][1]存放2i+1
a[i][0]存放0或1
如果2i+1是素數,則存放0,不為素數,則存放1
比如
a[3][1]=7
a[3][0]=1
當分子與分母只有一個是素數的時候,
a[i][0]+a[i+1][0]=1
+
,不是的話,則取-
。以此為條件,可以計算s(n)的值求最大值,我們只需要在每次s(n)加或減之後進行一次判斷,若s大於Max,則交換數值,第k項可以由公式
a[i][0]=2i-1
求得i,也就是k = (a[i][0]+1)/2
求最接近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; }
結果
算法學習——枚舉之基於素數的代數和