英雄会15题 阶乘与整除

本文介绍了一种高效判断n的阶乘(n!)是否为整数m的倍数的方法,采用因式分解技巧避免了传统求最大公约数方法的时间复杂度过高的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*******
英雄会15题
 
对于整数n,n的阶乘表示为n!定义如下 0! = 1 n! = n * (n - 1)! 给定n和m,问n!是否是m的倍数?
n和m全在32位整数范围内,m非0。 返回1和0表示整除和不整除。 
挑战规则: 
main函数可不用完成(3s)。
 
注释:
开始,用求最大公约数的方法,对每个i= 2~N求i和 m的最大公约数,直到m==1 结果,时间复杂度太高,超时
后来才想到,用因式分解的方法,果然没有超时,这里用了一个技巧,即用了n!里有几个factor的方法?
这是求n!末尾有几个0个问题,衍生的技巧. 
*****/
 
 
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
//#include<mem.h>

#define ByteBits 8

struct factors{

int factor,count;
};

struct factors  factor[32];
int factor_sep(int n){
int k = 0;
int i = 0;

memset(factor ,0,sizeof(int)* ByteBits * sizeof( struct factors));
if(n==0)return 0;
if(n == 1){
    factor[0].count++;
    factor[0].factor = 1;
    return 1;
}

for(i =2;i<sqrt(n);i++)
{
    while (n % i == 0 ){
        n /=i;
        factor[k].count++;
    }
    if(factor[k].count >0)
    {
        factor[k].factor = i;
        k++;
    }
    if(n ==1)break;
}

if(n > 1){
    factor[k].count++;
    factor[k].factor = n;
    k++;
}
    return k;
}

int divides (int n,int m)
{
    int i = 0;
    int k = 0;
    int n0 = n;
    int nc = 0;
    int nk = 0;
    if(n == 0)return 0;
    k = factor_sep(m);
    while(i < k){
        n0 = n;
        nc=0;   
        while(n0 > factor[k].factor){
             nc += n0/ factor[k].factor;
            if(nc>= factor[k] .count ){
                nk++;
                break;
            }
         }      
        i++;
    }   
    return k == nk;  
}
//start 提示:自动阅卷起始唯一标识,请勿删除或增加。
int main()
{   
    printf("%d",divides(4,12));
}
//end //提示:自动阅卷结束唯一标识,请勿删除或增加
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值