zoukankan      html  css  js  c++  java
  • 数学

    1.素数

    c.普通法

    /*
    普通法求素数
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    
    bool prime(int m)
    {
        int i,k;
        bool flag=true;
        k=sqrt(m);
        for(i=2; i<=k; ++i)
            if(m%i==0)
            {
                flag=false;
                break;
            }
        if(flag)return true;
        return false;
    }
    
    int main()
    {
        int i,j;
        for(i=2; i<100; ++i)
            if(prime(i))cout<<i<<' ';
        return 0;
    }
    View Code

    c2.筛法

    /*
    筛法求素数
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    using namespace std;
    
    int a[1024];
    void sieve(int n){//0是素数,-1不是素数
        memset(a,0,sizeof(a));
        int i,j,k;
        k=sqrt(n);
        a[1]=-1;
        for(i=2;i<=k;++i)
            if(a[i]==0)
                for(j=i+i;j<=n;j=j+i)
                    a[j]=-1;
    }
    
    int main(){
        int i,n;
        scanf("%d",&n);
        sieve(n);
        for(i=1;i<=n;++i)
            if(a[i]==0)
                printf("%d ",i);
        printf("
    ");
        return 0;
    }
    View Code

    kb2.1.1素数筛选(判断<MAXN的数是否素数)

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    /*
    素数筛选,判断小于MAXN的数是不是素数。
    notprime是一张表,为false表示是素数,true表示不是素数
    */
    const int MAXN=1000010;
    bool notprime[MAXN];//值为false表示素数,值为true表示非素数
    void init(){
        memset(notprime,false,sizeof(notprime));
        notprime[0]=notprime[1]=true;
        int i,j;
        for(i=2;i<MAXN;++i)
            if(!notprime[i]){
                if(i>MAXN/i)continue;//防止后面i*i溢出(或者i,j用long long)
                //直接从i*i开始就可以,小于i倍的已经筛选过了,注意是j+=i
                for(j=i*i;j<MAXN;j+=i)
                    notprime[j]=true;
            }
    }
    int main(){
        init();
        int i;
        for(i=0;i<100;++i)
            if(!notprime[i])printf("%d ",i);
        return 0;
    }
    View Code

    kb2.1.2素数筛选(筛选出小于等于MAXN的素数)

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    /*
    素数筛选,存在小于等于MAXN的素数
    prime[0]存的是素数的个数
    */
    const int MAXN=100;
    int prime[MAXN+1];
    void getPrime(){
        memset(prime,0,sizeof(prime));
        int i,j;
        for(i=2;i<=MAXN;++i){
            if(!prime[i])prime[++prime[0]]=i;
            for(j=1;j<=prime[0]&&prime[j]<=MAXN/i;++j){
                prime[prime[j]*i]=1;
                if(i%prime[j]==0)break;
            }
        }
    }
    int main(){
        getPrime();
        int i;
        for(i=1;i<=prime[0];++i)
            printf("%d ",prime[i]);
        return 0;
    }
    View Code

    2.最大公约数

    c.stl

    /*
    stl求最大公约数
    */
    #include<iostream>
    #include<stdio.h>
    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d
    ",__gcd(a,b));
        return 0;
    }
    View Code

    c2.枚举

    /*
    枚举求最大公约数
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    int main(){
        int a,b,i;
        scanf("%d%d",&a,&b);
        if(a>b){
            a=a^b;
            b=a^b;
            a=a^b;
        }
        for(i=a;i>=1;--i)
            if(a%i==0&&b%i==0)break;
        printf("%d
    ",i);
        return 0;
    }
    View Code

    3.辗转相除法(欧几里德算法)

    其中“a mod b”是指取 a ÷ b 的余数。
    例如,123456 和 7890 的最大公因子是 6,这可由下列步骤看出:
    a
    b
    a mod b
    123456
    7890
    5106
    7890
    5106
    2784
    5106
    2784
    2322
    2784
    2322
    462
    2322
    462
    12
    462
    12
    6
    12
    6
    0
     
     
     
     
     
     
     
     
     
     
     
    迭代形式:
    /*
    辗转相除法
    迭代形式
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    int gcd(int a,int b){
        int r;
        while(b!=0){
            r=a%b;
            a=b;
            b=r;
        }
        return a;
    }
    
    int main(){
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d
    ",gcd(a,b));
        return 0;
    }
    View Code

    递归:

    /*
    辗转相除法
    递归
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    int gcd(int a,int b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
    
    int main(){
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d
    ",gcd(a,b));
        return 0;
    }
    View Code

    递归化简:

    /*
    辗转相除法
    递归化简
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    int gcd(int a,int b){
        return b==0?a:gcd(b,a%b);
    }
    
    int main(){
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d
    ",gcd(a,b));
        return 0;
    }
    View Code

    ps:a,b的最大公约数记为(a,b),

    a,b的最小公倍数记为[a,b],

    它们的关系是:(a,b)*[a,b]=a*b。

    3.进制转换

    1.10进制转m进制

    /*
    10进制转m进制
    */
    #include<iostream>
    #include<string>
    using namespace std;
    
    int main()
    {
        int n,m;
        string ans;
        char num[16]= {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        cin>>n>>m;
        while (n)
        {
            ans=num[n%m]+ans;
            n=n/m;
        }
        cout<<ans;
        return 0;
    }
    View Code

    2.m进制转10进制

    /*
    m进制转10进制
    */
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    int main()
    {
        int m,ans=0;
        char n[9],num[16]= {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        cin>>n>>m;
        for (int i=0; i<=strlen(n)-1; i++)
            for (int j=0; j<=16; j++)
                if (n[i]==num[j])
                {
                    ans+=j*pow(m,strlen(n)-i-1);
                    break;
                }
        cout<<ans;
        return 0;
    }
    View Code

    4.质因数分解

    c.质因数分解

    /*
    质因数分解
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    
    void pf(int n){
        int i,k;
        for(i=2,k=sqrt(n);i<=k;++i){
            if(n%i==0){
                printf("%d ",i);
                n=n/i;
                --i;//遇到++i复位,可以分解出相同的质因子
                k=sqrt(n);//循环条件不直接写i<=sqrt(n);是因为这样可以避免重复开跟方
            }
        }
        printf("%d
    ",n);
    }
    
    int main(){
        int n;
        scanf("%d",&n);
        pf(n);
        return 0;
    }
    View Code

    c2.质因数分解

    /*
    质因数分解
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    
    const int MAXN=1024;
    
    int factors[MAXN][2];//[0]存质因子,[1]存个数
    int factCnt;//不同的质因子总个数
    
    void getFactors(int n){
        int i,k;
        factCnt=0;
        for(i=2,k=sqrt(n);i<=k;++i){
            if(n%i==0){
                factors[factCnt][0]=i;
                factors[factCnt][1]=1;
                n=n/i;
                while(n%i==0){
                    ++factors[factCnt][1];
                    n=n/i;
                }
                ++factCnt;
                k=sqrt(n);//循环条件不直接写i<=sqrt(n);是因为这样可以避免重复开跟方
            }
        }
        if(n>1){
            factors[factCnt][0]=n;
            factors[factCnt][1]=1;
            ++factCnt;
        }
    }
    
    int main(){
    
        int n;
        while(~scanf("%d",&n)){
    
            getFactors(n);
    
            printf("不同的质因子总个数:%d
    ",factCnt);
    
            int i,j;
            for(i=0;i<factCnt;++i){
                for(j=0;j<factors[i][1];++j){
                    printf("%d ",factors[i][0]);
                }
            }
    
            printf("
    ");
        }
    
        return 0;
    }
    View Code

    kb2.2素数筛选和合数分解

    /*
    素数筛选和合数分解
    */
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    //素数筛选和合数分解
    const int MAXN=10000;
    int prime[MAXN+1];
    void getPrime(){
        memset(prime,0,sizeof(prime));
        for(int i=2;i<=MAXN;i++){
            if(!prime[i])prime[++prime[0]]=i;
            for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++){
                prime[prime[j]*i]=1;
                if(i%prime[j]==0)break;
            }
        }
    }
    long long factor[100][2];
    int fatCnt;
    int getFactors(long long x){
        fatCnt=0;
        long long tmp=x;
        for(int i=1;prime[i]<=tmp/prime[i];i++){
            factor[fatCnt][1]=0;
            if(tmp%prime[i]==0){
                factor[fatCnt][0]=prime[i];
                while(tmp%prime[i]==0){
                    factor[fatCnt][1]++;
                    tmp/=prime[i];
                }
                fatCnt++;
            }
        }
        if(tmp!=1){
            factor[fatCnt][0]=tmp;
            factor[fatCnt][1]=1;
            fatCnt++;
        }
        return fatCnt;
    }
    int main(){
        getPrime();
        getFactors(12);//12=2*2*3;
        for(int i=0;i<fatCnt;i++)
            for(int j=0;j<factor[i][1];j++)
                printf("%d ",factor[i][0]);
        return 0;
    }
    View Code

    5.欧拉函数

    kb2.7.1分解质因数求欧拉函数

    /*
    分解质因数求欧拉函数
    */
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    //素数筛选和合数分解
    const int MAXN=10000;
    int prime[MAXN+1];
    void getPrime(){
        memset(prime,0,sizeof(prime));
        for(int i=2;i<=MAXN;i++){
            if(!prime[i])prime[++prime[0]]=i;
            for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++){
                prime[prime[j]*i]=1;
                if(i%prime[j]==0)break;
            }
        }
    }
    long long factor[100][2];
    int fatCnt;
    int getFactors(long long x){
        fatCnt=0;
        long long tmp=x;
        for(int i=1;prime[i]<=tmp/prime[i];i++){
            factor[fatCnt][1]=0;
            if(tmp%prime[i]==0){
                factor[fatCnt][0]=prime[i];
                while(tmp%prime[i]==0){
                    factor[fatCnt][1]++;
                    tmp/=prime[i];
                }
                fatCnt++;
            }
        }
        if(tmp!=1){
            factor[fatCnt][0]=tmp;
            factor[fatCnt][1]=1;
            fatCnt++;
        }
        return fatCnt;
    }
    
    int main(){
        getPrime();
        getFactors(8);//8=2*2*2;
        for(int i=0;i<fatCnt;i++)
            for(int j=0;j<factor[i][1];j++)
                printf("%d ",factor[i][0]);
        printf("
    ");
    
        int ret=8;//互质的数有1,3,5,7
        for(int i=0;i<fatCnt;i++)
            ret=ret/factor[i][0]*(factor[i][0]-1);
        printf("%d
    ",ret);
        return 0;
    }
    View Code

    kb2.7.2筛法欧拉函数

    /*
    筛法欧拉函数
    */
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    int euler[3000001];
    void getEuler(){
        memset(euler,0,sizeof(euler));
        euler[1]=1;
        for(int i=2;i<=3000000;i++)
            if(!euler[i])
                for(int j=i;j<=3000000;j+=i){
                    if(!euler[j])
                        euler[j]=j;
                    euler[j]=euler[j]/i*(i-1);
                }
    }
    int main(){
        getEuler();
        printf("%d
    ",euler[8]);//互质的数有1,3,5,7
        return 0;
    }
    View Code

    kb2.7.3求单个数的欧拉函数

    /*
    求单个数的欧拉函数
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    long long euler(long long n){
        long long ans=n;
        for(int i=2;i*i<=n;i++){
            if(n%i==0){
                ans-=ans/i;
                while(n%i==0)
                    n/=i;
            }
        }
        if(n>1)ans-=ans/n;
        return ans;
    }
    int main(){
        int e=euler(8);//互质的数有1,3,5,7
        printf("%d
    ",e);
        return 0;
    }
    View Code

    kb2.7.4线性筛(同时得到欧拉函数和素数表)

    /*
    线性筛(同时得到欧拉函数和素数表)
    */
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    const int MAXN=10000000;
    bool check[MAXN+10];
    int phi[MAXN+10];
    int prime[MAXN+10];
    int tot;//素数的个数
    void phi_and_prime_table(int N){
        memset(check,false,sizeof(check));
        phi[1]=1;
        tot=0;
        for(int i=2;i<=N;i++){
            if(!check[i]){
                prime[tot++]=i;
                phi[i]=i-1;
            }
            for(int j=0;j<tot;j++){
                if(i*prime[j]>N)break;
                check[i*prime[j]]=true;
                if(i%prime[j]==0){
                    phi[i*prime[j]]=phi[i]*prime[j];
                    break;
                }
                else{
                    phi[i*prime[j]]=phi[i]*(prime[j]-1);
                }
            }
        }
    }
    int main(){
        phi_and_prime_table(100);
        for(int i=0;i<tot;i++)
            printf("%d ",prime[i]);
        printf("
    ");
    
        printf("%d
    ",phi[8]);//互质的数有1,3,5,7
        return 0;
    }
    View Code

    6.欧几里德、扩展欧几里德

    一、欧几里德算法:即辗转相除法,用于求两个整数a,b的最大公约数

    见:最大公约数模板

    二、扩展欧几里德算法:对于不完全为0的非负整数a,b,gcd(a,b)表示a,b的最大公约数,必然存在整数对x,y,使得gcd(a,b)=ax+by。

    kb2.3扩展欧几里德算法(求ax+by=gcd的解以及逆元)

    /*
    扩展欧几里德算法(求ax+by=gcd的解以及逆元)
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    //返回d=gcd(a,b);和对应于等式ax+by=d中的x,y
    long long extend_gcd(long long a,long long b,long long &x,long long &y){
        if(a==0&&b==0)return -1;//无最大公约数
        if(b==0){x=1;y=0;return a;}
        long long d=extend_gcd(b,a%b,y,x);
        y-=a/b*x;
        return d;
    }
    
    //求逆元
    //ax=1(mod n)
    long long mod_reverse(long long a,long long n){
        long long x,y;
        long long d=extend_gcd(a,n,x,y);
        if(d==1)return (x%n+n)%n;
        else return -1;
    }
    
    int main(){
        long long a,b,x,y;
        scanf("%lld%lld",&a,&b);
        long long d=extend_gcd(a,b,x,y);
        printf("%lld x=%lld y=%lld
    ",d,x,y);
        return 0;
    }
    View Code

    7.逆元

    kb2.4.1扩展欧几里德法

    /*
    求逆元
    扩展欧几里德法
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    //返回d=gcd(a,b);和对应于等式ax+by=d中的x,y
    long long extend_gcd(long long a,long long b,long long &x,long long &y){
        if(a==0&&b==0)return -1;//无最大公约数
        if(b==0){x=1;y=0;return a;}
        long long d=extend_gcd(b,a%b,y,x);
        y-=a/b*x;
        return d;
    }
    
    //求逆元
    //ax=1(mod n)
    long long mod_reverse(long long a,long long n){
        long long x,y;
        long long d=extend_gcd(a,n,x,y);
        if(d==1)return (x%n+n)%n;
        else return -1;
    }
    
    int main(){
        long long a,n;
        scanf("%lld%lld",&a,&n);
        printf("%lld
    ",mod_reverse(a,n));
        return 0;
    }
    View Code

    kb2.4.1简洁写法

    注意:这个只能求a<m的情况,而且必须保证a和m互质

    /*
    求逆元
    简洁写法
    */
    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    //求ax=1(mod m)的x值,就是逆元(0<a<m)
    long long inv(long long a,long long m){
        if(a==1)return 1;
        return inv(m%a,m)*(m-m/a)%m;
    }
    
    int main(){
        long long a,m;
        scanf("%lld%lld",&a,&m);
        printf("%lld
    ",inv(a,m));
        return 0;
    }
    View Code

    kb2.4.3利用欧拉函数

    mod为素数,而且a和m互质

    /*
    求逆元
    利用欧拉函数
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    
    long long inv(long long a,long long mod){//为素数mod
        //return pow_m(a,mod-2,mod);
        return int(pow(a,mod-2))%mod;
    }
    
    int main(){
        long long a,mod;
        scanf("%lld%lld",&a,&mod);
        printf("%lld
    ",inv(a,mod));
        return 0;
    }
    View Code

     
    8.常规求幂、二分求幂、快速求幂

    HDU 2035 人见人爱A^B(二分求幂,快速求幂)

    题意:求A的B次方的后三位数字

    思路1:常规求幂,直接取余求解

    代码:

    /*
    常规求幂
    */
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int main(){
        int a,b;
        int ans;
        while(~scanf("%d%d",&a,&b)){
            if(a==0&&b==0) break;
            a=a%1000;//底数取余
            ans=1;
            while(b--){
                ans=(ans*a)%1000;//结果取余
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    思路2:二分求幂(一般)

    代码:

    /*
    二分求幂
    */
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int main(){
        int a,b;
        int ans;
        while(~scanf("%d%d",&a,&b)){
            if(a==0&&b==0) break;
            a=a%1000;//底数取余
            ans=1;
            while(b>0){//b==0时,所有的因子都已经相乘,循环结束。
                if(b%2==1)//1.奇数时,多出来的一项提前放到ans里  2.b==1时,完成结果和底数的最后一次相乘
                    ans=(ans*a)%1000;//结果取余
                a=(a*a)%1000;//二分操作
                b=b/2;//1.二分  2.b==1时,b/2=0,作为结束循环的条件
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    思路3:快速求幂(位操作)

    Hint:  这不就是二分求幂么!  只不过改动了两个位操作。。。

      b&1 可以判断是否为奇数,相当于 b%2==1

      b=b>>1 表示b的二进制数向右移一位,相当于 b=b/2;

    代码:

    /*
    快速求幂
    */
    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int main(){
        int a,b;
        int ans;
        while(~scanf("%d%d",&a,&b)){
            if(a==0&&b==0) break;
            a=a%1000;
            ans=1;
            while(b>0){
                if(b&1)//判断是否为奇数,相当于 if(b%2==1)
                    ans=(ans*a)%1000;
                a=(a*a)%1000;
                b=b>>1;//二进制向右移一位,相当于 b=b/2;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    9.矩阵快速幂

    /*
    矩阵快速幂
    */
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    #define N 2//N*N的矩阵
    const int MOD=1e9+7;//
    
    struct Matrix{
        int mat[N][N];
    };
    
    Matrix mul(Matrix a,Matrix b){
        Matrix ret;
        int i,j,k;
        for(i=0;i<N;++i){
            for(j=0;j<N;++j){
                ret.mat[i][j]=0;
                for(k=0;k<N;++k){
                    ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
                    ret.mat[i][j]%=MOD;
                }
            }
        }
        return ret;
    }
    
    Matrix pow_matrix(Matrix a,int n){
        Matrix ret;
        memset(ret.mat,0,sizeof(ret.mat));
        int i;
        for(i=0;i<N;++i){
            ret.mat[i][i]=1;
        }
        Matrix temp=a;
        while(n){
            if(n&1){
                ret=mul(ret,temp);
            }
            temp=mul(temp,temp);
            n>>=1;
        }
        return ret;
    }
    
    int main(){
        
        Matrix a;
        a.mat[0][0]=1,a.mat[0][1]=2;
        a.mat[1][0]=3,a.mat[1][1]=4;
        
        Matrix b;
        b=pow_matrix(a,2);
        
        printf("%d %d
    ",b.mat[0][0],b.mat[0][1]);
        printf("%d %d
    ",b.mat[1][0],b.mat[1][1]);
        
        return 0;
    }
    View Code

    10.二分法解一元三次方程

    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    using namespace std;
    
    /*
    二分法解一元三次方程ax^3+bx^2+cx+d=0
    方程必须是单调的才行吧?目测是这样
    */
    
    void dichotomy(int a,int b,int c,int d,double x1,double x2){//二分法求[x1,x2]之间的根
        double f1,f2;
        f1=a*x1*x1*x1+b*x1*x1+c*x1+d;
        f2=a*x2*x2*x2+b*x2*x2+c*x2+d;
    
        if(f1*f2>0){
            printf("无解
    ");
            return;
        }
        if(fabs(f1)<1e-8){
            printf("%f
    ",x1);
            return;
        }
        if(fabs(f2)<1e-8){
            printf("%f
    ",x2);
            return;
        }
    
        double x3,f3;
        do{
            x3=(x1+x2)/2;
            f3=a*x3*x3*x3+b*x3*x3+c*x3+d;
    
            if(f1*f3<0){
                x2=x3;
                f2=f3;
            }
            else if(f3*f2<0){
                x1=x3;
                f1=f3;
            }
            else{//f3==0
                printf("%f
    ",x3);
                return;
            }
        }while(fabs(f3)>=1e-8); //abs是取绝对值后再取整,而fabs是取绝对值之后不做操作
    
        printf("%f
    ",x3);
        return;
    }
    
    int main(){
    
        //求方程f=2x^3-4x^2+3x-6=0在区间[-10,10]的解
        dichotomy(2,-4,3,-6,-10,10);
    
        return 0;
    }
    View Code
  • 相关阅读:
    oozie的简易安装
    flume监控一个linux指定的一个文件夹的文件信息
    FastDFS图片服务器java后台的简单调用
    java对象与json互转
    final关键字详解
    文件压缩和解压缩工具类
    web上下文监听器ServletContextListener
    基本类型的相互转换
    用java代码在创建hbase表时指定region的范围
    String类的一些常用操作方法
  • 原文地址:https://www.cnblogs.com/gongpixin/p/5369754.html
Copyright © 2011-2022 走看看