整除问题,给定n和a,求最大的k,使n!可被a^k整除但不能被a^(k+1)整除

首先,这道题不可能直接算n!和a^k然后暴力解法,数太大了。那就乖乖找规律吧。
以输入n=6,a = 10,为例。
6! = 2 × 2 × 2 × 2 × 3 × 3 × 5 2\times2\times2\times2\times3\times3\times5 2×2×2×2×3×3×5,
10 = 2 × 5 2\times5 2×5,
如果6!可以被10^k整除,那么6!的素因数一定包含10的素因数,那么k就 =6!与10的相同素因数中,个数最少的那个素因数的个数。
6!与10的相同素因数有2和5,6!中2的数量是4个,5的数量是1个,故此例的k = 1。
以n=10,a=10为例再看一遍:
首先都分别筛选素因数
10! = 2 × 2 × 2 × 2 × 2 × 2 × 2 × 2 × 3 × 3 × 3 × 3 × 5 × 5 × 7 2\times2\times2\times2\times2\times2\times2\times2\times3\times3\times3\times3\times5\times5\times7 2×2×2×2×2×2×2×2×3×3×3×3×5×5×7;
10 = 2 × 5 2\times5 2×5;
看到10!和素因数有2,3,5,7,是包含10的所有素因数2和5的,故可以整除,在2和5中,素因数2的个数为8个,素因数5的个数为2个,故k = 2。
晚上迷迷糊糊敲的,好多其实不必要,懒得改了

#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>

using namespace std;

const int maxn = sqrt(1000)+1;

typedef struct
{
    int prime;
    int num;//对应素因数的个数,也就是幂指数
} primearray,*pa;

void initial(vector<int>&prime)//用筛除法求出素数列表
{
    bool isPrime[maxn];
    for(int i = 0; i<maxn; i++)
    {
        isPrime[i] = true;
    }
    isPrime[0] = false;
    isPrime[1] = false;
    for(int j = 2; j<maxn; j++)
    {
        if(!isPrime[j])
            continue;
        prime.push_back(j);
        for(int k = j*j; k<maxn; k += j)
        {
            isPrime[k] = false;
        }
    }
}
vector<primearray> getpa(vector<int>&prime,int x)//求出一个数所有的素因数,用num存储对应素因数个数
{
    vector<primearray>pa;
    int len = prime.size();
    for(int i = 0; i<len && prime[i] <= x; i++)
    {
        bool isprime = false;
        primearray pnode;
        pnode.num = 0;
        pnode.prime = prime[i];
        while(x%pnode.prime == 0)
        {
            x /= pnode.prime;
            isprime = true;
        }
        if(isprime)
            pa.push_back(pnode);
    }
    return pa;
}

int main()
{
    vector<int>prime;
    int n,a,k=0;
    while(scanf("%d%d",&n,&a) != EOF)
    {
        initial(prime);
        vector<primearray>pa = getpa(prime,a);
        int len = pa.size();
        for(int i = 0;i<pa.size();i++)
        {//因为无法直接拿n!来用,太大了,就从n一点点开始找同一个素因数,n找完了,就找n-1,最后到1,累加得到此素因数的个数
            int nn = n;
            while(nn>1)
            {
                int nt = nn;
                while( nt % pa[i].prime == 0)
                {
                    nt /= pa[i].prime;
                    pa[i].num++;
                }
                nn--;
            }
        }
        k = pa[0].num;//找出最小的num
        for(int j = 0;j<pa.size();j++)
        {
            if(pa[j].num == 0)
                break;
            int num = pa[j].num;
            if(k > pa[j].num)
                k = pa[j].num;
        }
        printf("%d\n",k);
    }
    return 0;
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值