本文主要是介绍蓝桥杯算法基础(32):素数,埃式筛法,快速幂,斐波那契与矩阵幂运算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
素数
有些人认为一个人一生中有三个周期,从他或她出生的那一天开始。 这三个周期是身体周期,情感周期的和智力的周期,他们有周期的长度为23,28, 和33天。每一个周期都有一个高峰。在一个周期的高峰期, 一个人在他/她在相应的领域(身体,情绪或精神)。 例如,如果它是心理曲线,思维过程会更清晰和集中会更容易。 由于三个周期有不同的周期,所以这三个周期的峰值一般发生在不同的时间。 我们想确定何时发生绝对高潮(所有三个周期的峰值发生在同一天)。 因为处于绝对高潮时人各方面均表现优异,因此人们想知道绝对高潮在哪一天出现。 对身体周期,情绪周期和智力周期,给出本年内他们各自的一个高潮日(不一定是第一个)后经过的天数p,e,i。另外,给出本年内已经经过的天数d(d>=0).求出在d所代表的日期多少天后, 三种周期的高潮日又一次在同一天出现。输入:输入数据有多组,每组测试数据占一行,有四个整数,p,e,i和d. p,e,i 分别代表从0开始计时,身体周期,情感周期和智力周期首次出现高潮的日期,要求编程计算经过d后多少天第一个绝对高潮出现,输入保证绝对高潮在21252内的某一天出现。输入以-1,-1,-1结束。输出:例如:Case 1: the next triple peak occurs in 1234 days.23 28 33 d1 d2 d3d1+23k1=x d2+28k2=x d3+33k3=xx≡d1 %23≡d2 %28≡d3 %33//延续上体的解题方法 //逐级合并法 x=a1(%m1)=a2(%m2)=a3(%m3) x=a1+m1y1 (1) x=a2+m2y2 ==>m1y1-m2y2=a2-a1这是一个线性方程可解出y1 linearEquation(m1,m2,a2-a1)带回(1).得特解x0=a1+m1*y1-->x=x0+k*lcm(m1,m2)得一个新方程//lcm(m1,m2),m1,m2得公倍数x≡x0 (%lcm(m1,m2))形成新的a(x0),新的m(lcm(m1,m2))public static void main(String[] args)throws Exceeption{Scanner sc= new Scanner(System.in);int t=1;List<long[]> aList=new ArrayList<long[]>();List<long> dList=new ArrayList<long>();while(sc.hasNext()){long[] a={sc.nextLong(),sc.nextLong(),sc.Long()};long d=sc.nextLong();if(a[0]==-1&&a[1]==-1&&a[2]=-1&&d==-1)break;else{aList.add(a);aList.add(d);}}for(int i=0;i<aList.size();i++){long[] a=aList.get(i);long d=dList.get(i);long[] m={23,28,33};long res=Case05_ExtGcd.linearEquationGroup(a,m);while(res<=d){res+=21252;//保证在21252内,就是以21252为模}System.out.println("Case"+(t++)+": the next triple peak occurs in"+(res-d)+"days");}}
埃式筛法
public static void mian(){long now=System.currentTimeMillis();m1(100000);System.out.println(”耗时“+(System.currentTimeMillis()-now)+"ms" ); }private static void m1(int N){//N是第N个素数//已知在整数X内大概有x/log(X)个素数//现在我们要逆推,要想求第N个素数,我们的整数范围是社么//length就是整数范围int n=2;while(n/log(n)<N){//n个数中,大概有n/log(n)个素数n++;}//开辟一个数组,下标是自然数,值是标记//基本思路是筛选法,把非素数标记出来//int[] arr=new int[n];int x=2;while(x<n){//标记过了。继续下一个if(arr[x]!=0){continue;}int k=2;//对每个x,我们都从2倍开始,对x的k倍,全部标记-1while(x*k<n){arr[x*k]=-1;k++;}x++;}//System.out,println(arr);//筛完之后,这个很长的数组里面非素数下标对应的值都是-1int sum=0;for(int i=2;i<arr.length;i++){//是素数,计数+1if(arr[i]==0){sum++;}if(sum==N){System.out,println(i);}} }
快速幂
反复平方 a^10 8 0 2 01 0 1 0 a^(2^3) a^(2^2) a^(2^1) a^(a^0);将次方转成二进制,哪一位有1,就乘以那一位所在的a的平方值 如 a^10=a^(2^3)*a(2^1)public static long ex2(long n,long m){long primeFangShu = n;//n的1次方long result=1;while(m!=0){if((m&1)==1){result*=pingFangShu;//每移位一次,幂累成方一次pingFangShu=pingFangShu*pingFangShu;//无论等不等于1,次方都成倍乘//右移一位m>>=1;}return result;}}
斐波那契与矩阵幂运算
(f1.f2)=(1,1)(f1,f2)*[0 1]=[f2.f3] //0+1=1=f1,1+1=2=f3=f1+f2[1 1](f1.f2)*[0 1]^2=[f3,f4][1 1]....递推[f1,f2]*[0 1]^n-1=[fn,fn+1][1 1]public static long fib(long n){if(n==1||n==2)return1;long[][] matrix={{0,1},{1,1}};long[][] res=Util.matrixPower(matrix,n-1);//矩阵的乘方res=Util.matrixMultiply(new long[][]{(1,1)},res);//矩阵的乘方与f1f2相乘return res[0][0];}public long[][] matrixPower(long[][] matrix,long p){//初始化结果为单位矩阵,对角线为1 long[][] result=new long[matrix.length][matrix[0].length]; //单位矩阵。相当于整数的1for(int i=0;i<result.length;i++){result[i][i]=1;}//平方数 long[][] pingFang=matrix;//一次方for(;p!=0;p++){while(p!=0){if((p&1)!=0){//当前二进制最低位1,将当前平方数乘到结果中result=matrixMultiply(result,pingFang);}平方数继续上翻pinFang=matrixMultiply(pingFang,pingFang);p>>1;}return result; }}
这篇关于蓝桥杯算法基础(32):素数,埃式筛法,快速幂,斐波那契与矩阵幂运算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!