• 算法学习——枚举之基于素数的代数和


    算法描述

    基于素数的代数和

    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;
    			
    	}
    

    结果

  • 相关阅读:
    ping 网关不同的原因(51cto博客搬迁)
    Linux Shell常用命令总结(51cto 博客搬迁)
    学生管理系统管理系统
    offset属性在各版本浏览器中的不同算法
    常用正则表达式
    select城市3级联动
    html5表单验证消息框
    清除浏览器默认选择效果
    排序之简单的冒泡排序
    简单的桶排序
  • 原文地址:https://www.cnblogs.com/stars-one/p/9650214.html
Copyright © 2020-2023  润新知