Mathematical algorithms common problem

Mathematical algorithms common problem

In the computer world, we usually still have to solve some math problems, here are some common mathematical algorithms to summarize the problem, hoping to slow the rate of forgetting.

The greatest common divisor and least common multiple

Greatest common divisor

Positive integers a and b is the greatest common divisor of the Convention refers to the maximum number of all common divisor of a and b in general use gcd(a, b)to represent the greatest common divisor of a and b, and the greatest common divisor used to solve the Euclidean algorithm (flounder phase division).

Euclidean algorithm based on the following theorem:

Set a, b are positive integers, gcd (a, b) = gcd (a, a% b)

Proof: set a = kb + r, where r k and b are divided by a quotient and a remainder obtained

There r = a - kb established

Let d is a common divisor of a and b,

Then the r = a - a divisor kb, r, have also d

Thus d is a common divisor of b and r

And r = a% b, d have a common divisor of b and a% b

Thus both the divisor d and b, a, b, and also the divisor of a% b

Because of the arbitrary nature of d, a and b have a common divisor is divisor of b and a% b

A = kb divisor of r, b, and same reason a% b + a is divisor of b and

Thus a divisor and the divisor b, a% b and b is equal to all, so the greatest common denominator are equal

即 gcd(a, b) = gcd(b, a % b)

If a <b, the result is the exchange of a and b; if a> b, then the data can quickly be smaller by the size of this theorem. So recursion boundary it? As we all know, any one of integers 0 and a greatest common divisor is a, this conclusion can be used as a recursive border. As a result, two key recursive get:

  1. Recursion: GCD (A, B) = GCD (B, A% B)
  2. Recursive boundary: GCD (A, 0) = A

Can then be obtained following code:

int gcd(int a, int b) {
  if(b == 0) return a;
  else return gcd(b, a % b);
}

The least common multiple

General use lcm (a, b) to represent the least common multiple of a and b.

The least common multiple of the greatest common divisor of solving be based on. When the greatest common divisor of a and b give d, can immediately obtain the least common multiple is ab & / D , ** ab ** may overflow because in actual operation, it is more appropriate wording is a / DB .

i.e., the greatest common divisor of a and b, a set of the set intersection b, and the least common multiple of a and b, and sets, as part of a multi ab common factor will be calculated once, we need to get rid of a common factor

Scores four operations

Score four arithmetic means given the numerator and denominator of two fractions, the required arithmetic result thereof, the following describes how to represent and to simplify a fraction.

Fractional representation and simplification

Fractional representation

For a score, the most simple form of writing is written improper fractions, i.e., whether the denominator larger or smaller molecules, retain their original number, it can be used to hold the structure:

struct Fraction{
    int up, down;
};

Three rules:

  1. The down non-negative, if the score is negative, then make up molecules can be negative
  2. If the score is exactly zero, the molecule which is a predetermined 0, the denominator is 1
  3. Numerator and denominator no common divisor except 1

Simplifying fractions

Simplification is mainly used to make Fraction variables meet three requirements expressed as a fraction, thus reducing steps are divided into the following three steps:

  1. Down if the denominator is negative, so the numerator and denominator have become its opposite number
  2. If the molecule up to 0, then let the denominator of 1
  3. About point: obtaining an absolute value of the denominator and the absolute values ​​of molecular greatest common divisor d, so that the molecule is then divided by the denominator d

code show as below:

Fraction reduction(Fraction result) {
    if(result.down < 0) {   // 分母为负数,令分子分母都变味相反数
        result.up = -result.up;
        result.down = -result.down;
    }
    if(result.up == 0) {    // 如果分子为 0,令分母为 1
        result.down = 1;
    }else { 
        int d = gcd(abs(result.up), abs(result.down));  // 分子分母的最大公约数
        result.up /= d; 
        result.down /= d;   // 约去最大公约数
    }
    return result;
}

Scores four operations

Scores need to be about addition and subtraction points, so they need about the separation of formula and can be calculated for the formula.

// 加法
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);
}

// 减法
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);
}

// 乘法
Fraction mul(Fraction f1, Fraction f2) {
    Fraction result;
    result.up = f1.up * f2.up;
    result.down = f2.down * f2.down;
    return reduction(result);
}

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

Fraction output

Output score requirements need to be the subject, has substantially the following note:

  1. Before output score, the need for simplification of its first
  2. If the score down denominator r is 1, indicating that the score is an integer, usually directly output molecule
  3. If the fraction r of molecules up the absolute value is greater than the denominator Down, indicating that the score is improper fractions, this time should be output mixed fraction form, i.e., the integer part of r.up / r.down , molecular moiety is abs (r.up) % down
  4. When the fraction described above do not satisfy the proper fraction for r, is output as

The following is an output Case:

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

Prime numbers

Also known as prime prime number, the number refers to a class of their own in addition to 1 and can not be divided by another integer. I.e., for a given positive integer n, if for any positive integer a (1 <a <n) , are n % a != 0then known prime number n, the number of otherwise engaged. Special attention is neither a prime number, nor composite.

Prime judgment

N determining whether a number is prime, it is necessary to determine whether n is 2,3, ......, n-1 is divisible, can not be divisible only when, in order to determine a prime number. However, we found that, if there is a digital number greater than about sqrt (n), then there must be a number which is about sqrt (n) is less than, we determined just from 2 to sqrt (n).

code show as below:

bool isPrime(int n) {
  if(n <= 1) return false;
  int sqr = (int)sqrt(n);	// 根号 n
  for(int i = 2; i <= sqr; i++) {
    if(n % i == 0) return false;
  }
  return true;	// n 是素数
}

If n is not close to the int variable upper bound of the range, there is a simpler wording:

bool isPrime(int n) {
  if(n <= 1) return false;
  for(int i = 2; i * i <= n; i++) {
    if(n % i == 0) return false;
  }
  return true;
}

Written questions that led when the upper bound of the range near the int variable i * i overflow (of course 10 9 or less will be safe), the solution is defined as the i-type long long, they will not overflow.

Get prime table

If we need to look at a wide range of all prime numbers, there is no quick way to do it?

"Screening" is a kind of a lot of screening method is very easy to understand, the core idea is:

Algorithms from small to large to enumerate all the numbers for each prime number, to weed out all of its multiples, and the rest are prime numbers, and in the process, the only thing we need given start condition is that 2 is a prime number, after It can be obtained by a process cycle.

Small to reach a large number of a, if not the screen to a previous step, then it must be a prime number, because if A is not a prime number, there must be a prime factor less than a, it must be screened out

We can use to simulate a bool array screen, if a [i] is true, then the prime number is, if a [i] is false, then the non-prime number.

bool isPrime[maxn];
vector<int> prime;

void getPrime() {
  for(int i = 0; i < maxn; i++) {
    isPrime[i] = true;	// 开始认为所有的都是素数
  }
  isPrime[0] = isPrime[1] = false;
  for(int i = 2; i < maxn; i++) {
    if(!isPrime[i]) {
      continue;	// 如果是非质数则跳过
    }
    prime.push_back(i);
    for(int j = i * i; j < maxn; j+=i) {
      isPrime[j] = false;
    }
  }
  return;
}

Decomposition quality factor

The so-called quality factor decomposition refers to a positive integer n is written as a product of prime or more forms.

But in the end it has to be written as the product of a number of distinct primes, so we might as well break out first prime table. Since each quality factor may appear more than once, so we might as well defined structure to hold the quality factor and the number is:

struct factor{
  int x, cnt;
}fac[10];

For a positive integer n, if it exists within the prime factors [2, n] range, these factors are below or sqrt (n), then at most one greater than sqrt (n), so the idea appears:

  1. 1 to enumerate all of the prime factors in the range of sqrt (n), determining whether p is a factor of n
    1. If p is a factor of n, then increase to an array fac prime factors p, and initializes the number thereof is 0, and if p is a factor n, let n p and constantly dividing, for each operation so the number p plus 1, p is not until the factor n
    2. If n is not a factor p, then skip
  2. If n is still greater than the end of the above step 1, there is described a n greater than sqrt (n) a factor, this factor was added at this time fac array.

code show as below:

PAT A1059

/*
    Author: Veeupup
 */
#include <cstdio>
#include <climits>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

const long maxn = 1e7;

vector<long> primes;     //  保存质数
bool isPrime[maxn];     //  质数判断

// 质数表初始化
void Initial() {
    fill(isPrime, isPrime + maxn, true);    // 所有的数字都初始化为 true,为质数,随后筛
    isPrime[0] = isPrime[1] = false;
    for(long i = 2; i < maxn; i++) {
        if(!isPrime[i]) 
            continue;   // 如果 i 不是质数,则跳过
        primes.push_back(i);
        for(long j = i * i; j < maxn; j += i) {
            isPrime[j] = false; // i 的倍数被标记为合数
        }
    }
    return;
}

struct Factor {
    long x, cnt;
}fac[10];   // 保存质因子

int main()
{
    Initial();  // 初始化质数表
    long n, num = 0;    // num 为不同质因子的个数
    scanf("%ld", &n);
    if(n == 1) {
        printf("1=1");
    }else {
        printf("%ld=", n);
        long sqr = (long)sqrt(n);
        // 枚举根号 n 以内的质因子
        for (int i = 0; i < primes.size() && primes[i] < sqr; i++)
        {
            if(n % primes[i] == 0) {
                fac[num].x = primes[i];
                fac[num].cnt = 0;
                while (n % primes[i] == 0)
                {
                    fac[num].cnt++;
                    n /= primes[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("%ld", fac[i].x);
            if(fac[i].cnt > 1) {
                printf("^%d", fac[i].cnt);
            }
        }
    }
    
    return 0;
}

Guess you like

Origin www.cnblogs.com/veeupup/p/12561242.html