1.最大公约数
原理:辗转相除法
int gcd(int a,int b)
{
return b==0? a: gcd(b,a%b);
}
2.最小公倍数
原理:最小公倍数等于这两个数的乘积除最大公约数
int icm(int a,int b)
{
return a*b/gcd(a,b);
}
3.素数
**普通的方法:**
int is_prime(int a){
if(a<=1){//一定不能少
return 0;
}
for(int i=2;i<=sqrt(a);i++){//注意这里必须是"="号
if(a%i==0){
return 0;
}
}
return 1;
}
**6倍法快速判断素数**
bool is_sprime(int x){
if(x==1)return false;//1不是素数
if(x==2||x==3||x==5){//2,3,5是素数
return true;
}
if(x%2==0||x%3==0){//2和3的倍数一定不是素数
return false;
}
for(int i=5;i<=sqrt(x);i+=6){
if(x%i==0||x%(i+2)==0){
return false;
}
}
return true;
}
**欧拉筛算法**
应用:求n以内的所有素数
bool check[1000001];//标记合数
int prime[1000001],cnt=0;//储存素数 ,cnt记录素数个数
void isprime(int n){//求n以内的所有素数
check[0]=true;//0不是素数
check[1]=true;//1不是素数
for(int i=2;i<=n;i++)
{
if(!check[i])prime[cnt++]=i;//若当前数i没有被之前的所有数筛掉,表明i是素数,将i添加进素数表prime
for(int j=0;j<cnt&&i*prime[j]<=n;j++)//注意i*prime[j]不要超过n的上限
{
check[i*prime[j]]=true;//将当前素数prime[j]的i倍标记为合数
if(i%prime[j]==0)break;//关键步骤:保证每个合数只被筛一次
}
}
}
4.判断回文数
原理:回文数反转过来不变
int huiwen(int m){
int n=m,t=0;
while(n){//反过来的值给t
t=t*10+n%10;
n/=10;
}
return t==m?1:0;//判断前后是否相等
}
5.质因数
1.整数由两个质数相乘,求最大的质因数(说明整数是奇数)
原理:一个整数能且只能分解成一组质因数的乘积,
scanf("%d",&n);
for(int i=2;i<=n;++i)
if(n%i==0)
{
printf("%d",n/i);
return 0;
}
2.将一个自然数n分解成若干个质因数相乘
方法一思想:首先建立素数表,然后用n除与素数表中的每一个质数,给n赋予除了之后的值,直到n=1为止
int fenjiezys(int n){
isprime(n);//利用欧拉筛建立素数表
int i=0;
while(n!=1){//当等于1是所有质因数找完
if(n%prime[i]==0){//可以除尽就是质因数
printf("%d",prime[i]);//输出质因数
n/=prime[i];//继续找下一个质因数
continue;//一定要加。因为质因数可以相同
}
i++;//便利素数表
}
}
方法二思想:Pollard Rho算法,递归处理
zhiyinshu(n,2);//调用 函数
void zhiyinshu(int t,int k){
if(t==k)printf("%d",k);
else if(!(t%k)){
printf("%d*",k);
zhiyinshu(t/k,k);
}else{
zhiyinshu(t,k+1);
}
}
6.水仙花数
水仙花数:n位正整数(n>=3),他的每个位上的数字的n次幂之和等于他本身
应用:判断n是不是水仙花数
int shuixianhau(int n){
int len=0,m=n,t=1,sum=0,ans;
while(m){//计算位数
m/=10;
len++;
}
m=n;
for(int i=0;i<len;i++){//取n的每一位数
t=m%10;
ans=1;//存放每一位数的len次方的值
for(int i=0;i<len;i++){//计算每一位数的len次方
ans*=t;
}
sum+=ans;
m/=10;
}
return sum==n?1:0;//当前后相等就是水仙花数
}
7.完全数
完全数:等于其所有因子之和
应用:输出n的完全数
int wanquanshu(int n){
for(int i=1;i<n;i++){//找n的因数
if(n%i==0){//是因数则属于n的一个完全数
printf("%d ",i);//输出n的所有完全数
}
}
}
8.自守数
自守数:自守数的平方末尾几位数等于这个数的本身 如:376*376=141376//末尾三位仍然376
int zishoushu(int n){
int m=n,len=1;
while(m){
m/=10;
len*=10;// 不用计算位数,字节算出除数
}
if(n*n%len==n){
return 1;
}else{
return 0;
}
}