zoukankan      html  css  js  c++  java
  • 算法笔记 第5章 入门篇(3) --数学问题 学习笔记

    5.1 简单数学

    PAT A1069/B1019 The Black Hole of Numbers (20分)

    For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in non-increasing order first, and then in non-decreasing order, a new number can be obtained by taking the second number from the first one. Repeat in this manner we will soon end up at the number 6174 -- the black hole of 4-digit numbers. This number is named Kaprekar Constant.

    For example, start from 6767, we'll get:

    7766 - 6677 = 1089
    9810 - 0189 = 9621
    9621 - 1269 = 8352
    8532 - 2358 = 6174
    7641 - 1467 = 6174
    ... ...

    Given any 4-digit number, you are supposed to illustrate the way it gets into the black hole.

    Input Specification:

    Each input file contains one test case which gives a positive integer N in the range (.

    Output Specification:

    If all the 4 digits of N are the same, print in one line the equation N - N = 0000. Else print each step of calculation in a line until 6174 comes out as the difference. All the numbers must be printed as 4-digit numbers.

    Sample Input 1:

    6767

    Sample Output 1:

    7766 - 6677 = 1089
    9810 - 0189 = 9621
    9621 - 1269 = 8352
    8532 - 2358 = 6174

    Sample Input 2:

    2222

    Sample Output 2:

    2222 - 2222 = 0000
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    bool cmp(int a,int b){
        return a > b;
    }
    void toarray(int n,int num[]){
        for(int i=0;i<4;i++){
            num[i] = n%10;
            n /= 10;
        }
    }
    int tonumber(int num[]){
        int sum = 0;
        for(int i=0;i<4;i++){
            sum = sum*10 + num[i];
        }
        return sum;
    } 
    int main(){
        int n;
        scanf("%d",&n);
        int num[5];
        while(1){
            int max1,min1;
            toarray(n,num);
            sort(num,num+4);
            min1 = tonumber(num);
            sort(num,num+4,cmp);
            max1 = tonumber(num);
            n = max1 - min1;
            printf("%04d - %04d = %04d
    ",max1,min1,n);
            if(n==6174 || n==0){
                break;
            }
        }
        return 0;
    }

    5.2 最大公约数与最小公倍数

    5.2.1 最大公约数

    1818: 最大公约数

    题目描述

    输入两个正整数,求其最大公约数。

    输入

    测试数据有多组,每组输入两个正整数。

    输出

    对于每组输入,请输出其最大公约数。

    样例输入

    49 14

    样例输出

    7
    #include<cstdio>
    int gcd(int a,int b){
        if(b == 0)
             return a;
        else 
            return gcd(b,a%b);
    }
    int main(){
        int m,n;
        while(scanf("%d%d",&m,&n)!=EOF){
            printf("%d
    ",gcd(m,n));
        }
        return 0;
    }

    5.3 分数的四则运算

    5.3.1 分数的表示和化简

    1.分数的表示

    struct Fraction{

      int up,down;

    };

    规定:

    ①使down为非负数。如果分数为负,那么令分子up为负即可。

    ②如果该分数恰为0,那么规定其分子为0,分母为1.

    ③分子和分母没有除了1以外的公约数。

    2.分数的化简

    Fraction reduction(Fraction result){
        if(result.down < 0){
            result.up = -result.up;
            result.down = - result.down;
        }
        if(result.up == 0){
            result.down = 1;
        }else{
            int d = gcd(abs(result.up),abs(result.down));
            result.up /= d;
            result.down /= d;
        }
        return result;
    }

    5.3.2 分数的四则运算

    1.分数的加法

    Fraction add(Fraction f1,Fraction f2){
        Fraction result;
        result.up = f1.up * f2.down + f2.up*f1.down;
        result.down = f1.down * f2.down;
        return reduction(result);
    }

    2.分数的减法

    Fraction minu(Fraction f1,Fraction f2){
        Fraction result;
        result.up = f1.up * f2.down - f2.up*f1.down;
        result.down = f1.down * f2.down;
        return reduction(result);
    }

    3.分数的乘法

    Fraction multi(Fraction f1,Fraction f2){
        Fraction result;
        result.up = f1.up * f2.up;
        result.down = f1.down * f2.down;
        return reduction(result);
    }

    4.分数的除法

    Fraction divide(Fraction f1,Fraction f2){
        Fraction result;
        result.up = f1.up * f2.down;
        result.down = f1.down * f2.up;
        return reduction(result);
    }

    只有当除数不为0时,才能用上面的函数进行计算。

    5.3.3 分数的输出

    void showResult(Fraction r){
        r = reduction(r);
        if(r.down == 1){
            printf("%lld",r.up);
        }else if(abs(r.up) > r.down){
            printf("%d %d/%d",r.up/r.down,abs(r.up) % r.down,r.down);
        }else{
            printf("%d/%d",r.up,r.down);
        }
    }

    5.4 素数

    素数又称为质数,是指除了1和本身之外,不能被其他数整除的一类数。1既不是素数,也不是合数。

    5.4.1 素数的判断

    bool isPrime(int n){
        if(n <= 1)
            return false;
        int sqr = (int)sqrt(1.0*n);
        for(int i=2;i<=sqr;i++){
            if(n % i == 0)
                return false;
        }
        return true;
    }
     sqrt的作用为一个浮点数开根号,需要添加math.h头文件。

    5.4.2 素数表的获取
    const int maxn = 101; //表长 
    int prime[maxn],pNum = 0; //prime数组存放所有素数,pNum为素数个数 
    bool p[maxn] = {0}; //p[i] == true表示i是素数 
    void Find_Prime(){
        for(int i=1;i<maxn;i++){
            if(isPrime(i) == true){
                prime[pNum++] = i;
                p[i] = true;
            }
        }
    }

    埃氏筛法:

    例子:求1~15中的所有素数

     PAT B1013 数素数 (20分)

    令 Pi​​ 表示第 i 个素数。现任给两个正整数 MN104​​,请输出 PM​​ 到 PN​​ 的所有素数。

    输入格式:

    输入在一行中给出 M 和 N,其间以空格分隔。

    输出格式:

    输出从 PM​​ 到 PN​​ 的所有素数,每 10 个数字占 1 行,其间以空格分隔,但行末不得有多余空格。

    输入样例:

    5 27

    输出样例:

    11 13 17 19 23 29 31 37 41 43
    47 53 59 61 67 71 73 79 83 89
    97 101 103
    #include<cstdio>
    #include<cmath>
    const int maxn = 10010;
    long long prime[maxn];
    bool isPrime(int a){
        for(int i=2;i<=sqrt(a);i++){
            if(a % i == 0){
                return false;
            }
        }
        return true;
    } 
    int main(){
        int m,n;
        scanf("%d%d",&m,&n);
        int num = 1;
        for(int i=2;num<=n;i++){
            if(isPrime(i)==true){
                prime[num++] = i;
            }
        }    
        int count=0;
        for(int i=m;i<=n;i++){
            printf("%d",prime[i]);
            count++;
            if(count %10!=0 && i<n)
                printf(" ");
            else
                printf("
    ");
        }
        return 0;
    }

     5.5 质因子分解

    所谓质因子分解是指将一个正整数n写成一个或多个质数的乘积形式,例如6 = 2 * 3,8 = 2 * 2 * 2,180 = 2 * 2 * 3 *3 *5。

    定义结构体factor,用来存放质因子及其个数,如下所示:

    struct factor{

      int x,cnt;

    }fac[10];

    例如对180来说,fac数组如下:fac[0].x = 2; fac[0].cnt = 2;  fac[1].x = 3; fac[1].cnt = 2;   fac[2].x = 5;fac[2].cnt = 1;

    PAT A1059 Prime Factors (25分)

    Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p1​​k1​​​​×p2​​k2​​​​××pm​​km​​​​.

    Input Specification:

    Each input file contains one test case which gives a positive integer N in the range of long int.

    Output Specification:

    Factor N in the format = p1​​^k1​​*p2​​^k2​​**pm​​^km​​, where pi​​'s are prime factors of N in increasing order, and the exponent ki​​ is the number of pi​​ -- hence when there is only one pi​​, ki​​ is 1 and must NOT be printed out.

    Sample Input:

    97532468

    Sample Output:

    97532468=2^2*11*17*101*1291
    #include<cstdio>
    #include<cmath>
    bool isprime(int n){
        if(n<=1){
            return false;
        }
        int sqr = (int)sqrt(1.0*n);
        for(int i=2;i<=sqr;i++){
            if(n%i == 0)
                return false;
        }
        return true;
    }
    const int maxn = 100010;
    int prime[maxn],pNum=0;
    void Find_Prime(){
        for(int i=1;i<maxn;i++){
            if(isprime(i)){
                prime[pNum++] = i;
            }
        }
    }
    struct factor{
        int x;
        int cnt; 
    }fac[10];
    int main(){
        Find_Prime();
        int n,num=0;
        scanf("%d",&n);
        if(n==1){
            printf("1=1
    ");
        }else{
            printf("%d=",n);
            int sqr = (int)sqrt(n*1.0);
            for(int i=0;i<pNum && prime[i]<=sqr;i++){
                if(n % prime[i]==0){
                    fac[num].x = prime[i];
                    fac[num].cnt = 0;
                    while(n%prime[i]==0){
                        fac[num].cnt++;
                        n /= prime[i];
                    }
                    num++;
                    if(n == 1)
                        break;
                }
            }
            if(n != 1){
                fac[num].x = n;
                fac[num++].cnt = 1;
            }
        }
        for(int i=0;i<num;i++){
            if(i > 0)
                printf("*");
            printf("%d",fac[i].x);
            if(fac[i].cnt>1)
                printf("^%d",fac[i].cnt);
        }
        return 0;
    }

    5.6 大整数运算

    5.6.1 大整数的存储

    使用数组存储大整数即可,例如定义int型数组d[1000],那么这个数组中的每一位就代表了存放的整数的每一位。如将整数235813存储到数组中,

    则有d[0]=3, d[1]=1, d[2]=8, d[3]=5 ,d[4]=3, d[5]=2,即整数的高位存储在数组的高位,整数的低位存储在数组的低位。但是把整数按字符串%s读入的时候,实际上是逆味存储的,即str[0] = ‘2',

    str[1] = '3' ...,因此在读入之后需要在另存为至d[]数组的时候反转一下。

    会定义一个int型变量len来记录长度,并和d数组组合成结构体。

    struct bign{

      int d[1000];

      int len;

      bign(){

        memset(d,0,sizeof(d));

        len = 0;

      }

    };

    将字符串转换为bign结构体

    bign change(char str[]){
        bign a;
        a.len = strlen(str);
        for(int i=0;i<a.len;i++){
            a.d[i] = str[a.len - i -1] - '0';
        }
        return a;
    }

    比较两个bign变量的大小

    int compare(bign a,bign b){
        if(a.len > b.len)
            return 1;
        else if(a.len < b.len)
            return -1;
        else{
            for(int i = a.len - 1;i>=0;i--){
                if(a.d[i] > b.d[i])
                    return 1;
                else if(a.d[i] < b.d[i])
                    return -1;
            }
            return 0;
        }
    }

    5.6.2 大整数的四则运算

    bign add(bign a,bign b){
        bign c;
        int carry = 0;
        for(int i=0;i<a.len || i<b.len;i++){
            int temp = a.d[i] + b.d[i] + carry;
            c.d[c.len++] = temp % 10;
            carry = temp / 10;
        }
        if(carry != 0){
            c.d[c.len++] = carry;
        } 
        return c;
    }
    bign sub(bign a,bign b){
        bign c;
        for(int i=0;i<a.len || i<b.len;i++){
            if(a.d[i] < b.d[i]){
                a.d[i+1]--;
                a.d[i] += 10;
            }
            c.d[c.len++] = a.d[i] - b.d[i];
        }
        while(c.len - 1>=1 && c.d[c.len - 1]==0){
            c.len--;
        }
        return c;
    }
    bign multi(bign a,int b){
        bign c;
        int carry = 0;
        for(int i=0;i<a.len;i++){
            int temp = a.d[i]*b + carry;
            c.d[c.len++] = temp%10;
            carry = temp/10;
        }    
        while(carry != 0){
            c.d[c.len++] = carry % 10;
            carry /= 10;
        }
        return c;
    }
    bign divide(bign a,int b,int &r){
        bign c;
        c.len = a.len;
        for(int i=a.len - 1;i>=0;i--){
            r = r*10+ a.d[i];
            if(r < b)
                c.d[i] = 0;
            else{
                c.d[i] = r/b;
                r = r%b;
            }
        }
        while(c.len - 1>=1 && c.d[c.len - 1] == 0){
            c.len--;
        } 
        return c;
    }

    5.7 扩展欧几里得算法

     
  • 相关阅读:
    机器学习---聚类算法
    机器学习解决问题的框架
    17个机器学习的常用算法!
    机器学习---理论篇
    golang 调用cmd执行EXE
    队列(自定义列表实现自定义队列)
    栈Stack(使用自定义链表实现自定义栈)
    链表( 自定义链表)
    队列(动态数组实现自定义队列)
    栈Stack(动态数组实现自定义栈)
  • 原文地址:https://www.cnblogs.com/coderying/p/12245895.html
Copyright © 2011-2022 走看看