【菜鸟er】常用模板_最大公约数(快速算法)+常用模板_大数阶乘

#include <bits/stdc++.h>
using namespace std;
//最小公倍数:lcm(a,b)=a/gcd(a,b)*b
//最大公约数:
//辗转相除法:
int gcd(int a,int b)
{
    while(b!=0)
    {
        int r=b;
        b=a%b;
        a=r;
    }
    return a;
}
//划归思想:
/**
 1.m为奇数时:
    (1)n也为奇数:gcd(m,n) = gcd((m+n)/2,(m-n)/2) ;
    (2)n为偶数:  gcd(m,n) = gcd(m,n/2) ;
 2.m为偶数时:
   (1) n也为偶数:gcd(m,n) = gcd(m/2,n/2);
   (2) n为奇数:  gcd(m,n) = gcd(m/2,n);
 3.m == n 时,gcd(m,n) = m 退出
*/
int stein_gcd( int m , int n )
{
    int temp,total=0 ;
    if ( m < n ){
         temp = m ;
         m = n ;
         n = temp ;
    }
    if ( n == 0 )
    return 0 ;
    while ( m != n ){
          if ( m & 1) {
/* 如果m 为奇数, 因为奇数的后面总有一个1,所以可以通过与1且一下来判断是否是偶数*/
               if ( n & 1) {/* m,n都为奇数*/
                    temp = m ;
                    m = (m+n)>>1 ;
                    n = (temp-n)>>1;
               }
               else{
                    n  >>= 1 ;
               }
          }
          else {/* m为偶数 */
               if ( n & 1) {/*n 为奇数*/
                    m >>= 1 ; /*由于在这个过程中,m可能小于n ,所以要判断一下*/
                    if ( m < n ){
                         temp = m ;
                         m = n ;
                         n = temp ;
                    }
               }
               else{
                    m >>= 1 ;
                    n >>= 1 ;
                    total ++ ; /*记录缩小的倍数*/
               }
          }
    }
    m <<= total ; /*还原大小*/
    return m ;
}
int main(){
    cout<<gcd(456892312,1234568)<<endl;
    cout<<stein_gcd(456892312,1234568)<<endl;
    return 0;
}
#include<iostream>
#include<cmath>
using namespace std;

int bit[3000];
//临界值是33
void update(int hbit)  // 进位
{
    for(int i = 0; i <= hbit; i++)  {
        if(bit[i] > 9)  {
            bit[i+1] += bit[i] / 10;
            bit[i] %= 10;
        }
    }
}
int fact(int n) // 返回n!结果的位数
{
    double sum = 0;
    for(int i = 1; i <= n; i++)
        sum += log10(i);
    int digit = (int)sum+1;

    for(int i = 0; i <= digit; i++)
        bit[i] = 0;
    bit[0] = 1;
    int hbit = 1;
    for(int i = 2; i <= n; i++)  {
        int j = digit;
        while(bit[j] == 0)
            hbit = --j;
        for(int j = 0; j <= hbit; j++)
            bit[j] *= i;
        update(hbit);
    }
    int j = digit;
    while(bit[j] == 0)
        hbit = --j;
    return hbit;
}

int main()
{
    int n;
    while(~scanf("%d", &n)){
        int hbit = fact(n);
        while(hbit >= 0)
            printf("%d", bit[hbit--]);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/f_zmmfs/article/details/81291455