素数 , 整数 , 余数
最大公约数 最小公倍数
辗转相除法
a = ka * i + a1 ;
b = kb * i + b1;
假设a表示成 一个数k 乘以某一个数字i 再加上一个余数a1
也就是 用i除a 商是ka 余数是a1
(a + b) % i = (ka + kb) * i % i + (a1 + b1) % i;
= 0 + (a1 + b1) % i;
= a % i + b % i;
计算中涉及到取余数的问题的时候,两个数相加取余数 和 两个数分别取余数再相加 是 一样的
辗转相除法就是:
a = ka * i;
b = kb * i;
假设 a小
(b -a) = (kb - ka) * i;
求 [a, b] 最大公约数 -----------> 求[b-a, a] 最大公约数
减几个a都可以 b-a 就变成 b%a
[a, b] -------> [b % a, a];
递归方法
#include <iostream>
#include <cstdio>
#include <string.h>
#include <iomanip>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#define PI atan(1.0)*4
using namespace std;
int gcd(int a, int b)
{
if(a == 0)
return b;
return gcd(b % a, a);
}
int mimo(int a, int n, int p)
{
int x = 1;
for(int i = 0; i < n; i++)
{
x = x * a % p;
}
return x;
}
int main()
{
//素数 , 整数 , 余数
//最大公约数 最小公倍数
/*
最大公约数
笨的方法 效率不高
int a = 15;
int b = 40;
for(int i = a; i >= 1; i--)
{
if(a % i ==0 && b % i == 0)
{
cout << i << endl;
break;
}
}
*/
/**辗转相除法**/
/*
a = ka * i + a1 ;
b = kb * i + b1;
假设a表示成 一个数k 乘以某一个数字i 再加上一个余数a1
也就是 用i除a 商是ka 余数是a1
(a + b) % i = (ka + kb) * i % i + (a1 + b1) % i;
= 0 + (a1 + b1) % i;
= a % i + b % i;
计算中涉及到取余数的问题的时候,两个数相加取余数 和 两个数分别取余数再相加 是 一样的
辗转相除法就是:
a = ka * i;
b = kb * i;
假设 a小
(b -a) = (kb - ka) * i;
求 [a, b] 最大公约数 -----------> 求[b-a, a] 最大公约数
减几个a都可以 b-a 就变成 b%a
[a, b] -------> [b % a, a];
*/
/*
int a = 15;
int b = 40;
for(;;)
{
if(a == 0)
{
cout << b << endl;
break;
}
int t = a;
a = b % a;
b = t;
}
*/
/**递归方法**/
/*
int a = 15;
int b = 40;
cout << gcd(a, b) << endl;
*/
/** 最小公倍数 = a * b / gcd(a, b) **/
/*
cout << a * b / gcd(a, b);
*/
/** 求 a 的 n 次幂 对 p 取模**/
cout << mimo(3, 50 ,17);
return 0;
}