zoukankan      html  css  js  c++  java
  • scau 8637 阶乘与因子 筛素数

    时间限制:500MS  内存限制:1000K
    提交次数:189 通过次数:46

    题型: 编程题   语言: G++;GCC

     

    Description

    游戏玩了很久总会厌的,连Lyd的蚂蚁都被放生了......(参看题目:盒子上的蚂蚁)
    于是Mr.Chen 看大家很无聊,就让Lord.Suno 负责新生赛出题的事情,然后大家一起帮忙出题。
    Lyd 想了很久,想到一个题目,题意如下:
    给出两个数,正整数n(n<10)和质数m(m<100),求满足n!=k * m^p 最大的整数p(k 为正
    整数)。
    题目拿给Suno看,他说,这也太简单了吧......三秒钟写完核心代码:
    sum=1;p=0;
    for(i=1;i<=n;i++)
        sum*=i;
    while(sum%m==0)
    {
        p++;
        sum/=m;
    }
    Lyd 想,那n<1000 吧,这样sum太大就存不下了。。。Suno 说,那也简单,不存直接算,就算你来
    个10000 的也不怕。十秒钟的事情:
    p=0;
    for(i=1;i<=n;i++)
    {
        q=i;
        while(q%m==0)
        {
            p++;
            q/=m;
        }
    }
    -_-!!!
    无奈之下Lyd 说,那m 不要质数了,不能直接除,然后增大规模,2<=m<5000,您能算不?Suno
    想了想,说稍微处理一下,然后多用几次上面的代码,执行完再!@#$%^&*,就OK 啦......
    被Suno 多次BS 之后,Lyd 说,好吧,n<10^8,用扫描1-n 的方法超时,不让你扫......Suno 说,
    呃,这样会不会太难......Lyd 得意地笑了,嘿嘿这回不会了吧!Suno 回了一句,不用for 用另一种更快
    的方法而已,m<10^6 都没问题,我的意思是这思路有点巧妙,当新生赛会不会太难?也行,就这样吧,
    相信想得到的,反正题目是你出的,没人做得出是你郁闷。。。Lyd 再次囧......



    输入格式

    测试数据第一行是一个数T(T<=10000),表示测试数据的组数。
    之后每一行代表一组测试数据。
    每一组测试数据有两个数,n(0<n<10^8)和m(2<=m<10^6)。


    输出格式

    对于每组测试数据,输出一行,每行一个数,能满足n!=k * m^p 的最大的p。


     

    输入样例

    2
    4 6
    6 3
    


     

    输出样例

    1
    2
    


     

    提示

    
    

     

    来源

     lyd 

     

    作者

     admin
     
    pp教了我怎么方便的唯一分解后这道题就算很水了
    题目实际就是要你求从1*2*3*。。n中,能够乘出多少个m,那么我们可以把m唯一分解,对于m的每个质因数k,其个数为p,在n!中k的个数可以快速求出,为c,那么c/p就是一个可能的答案,在所有的可能答案中取一个最小的就好了
    求n!中k的个数?还记得求n!中末尾0的个数吗,其实就是求10的个数,其实就是求2和5的个数。。。。。。
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int N = 1e6;
    typedef long long ll;
    int n, m, c;
    int fr[N], p[30], mp[30];
    int pri[N]= {0};
    int pnum = 0;
    
    void pre()
    {
        for(int i = 2; i < N; ++i) {
            if(!fr[i]) {
                    pri[ pnum++ ] = i;
                    fr[i] = i;
            }
            for(ll j = 0; j < pnum && i * pri[j] < N; ++j) {
                fr[i * pri[j]] = pri[j];
                if(!(i % pri[j])) break;
            }
        }
    }
    void get(int x) { /// 对x唯一分解,mp存储质因数序列,p存储每个质因数对应的个数
        c = 0; int t = -1;
        while(x > 1)
        {
            if(fr[x] != t) {
                    c++;
                    mp[c] = fr[x];
            }
            p[c]++;
            t = fr[x];
            x /= fr[x];
        }
    }
    int calc(int k) { ///求1~n中能组成的k的个数
        int cnt = 0;
        ll mult = k;
        while(mult <= n)
        {
            cnt += n / mult;
            mult  = mult * k;
        }
        return cnt;
    }
    int main()
    {
    
        pre();
        int _; scanf("%d", &_);
        while(_ --)
        {
            scanf("%d%d", &n, &m);
            memset(p, 0, sizeof p);
            get(m);
            int ans = 0x3f3f3f3f;
            for(int i = 1; i <= c; ++i) 
            {
                ans = min(ans, calc(mp[i]) / p[i]);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    编写一个供浏览器端使用的NPM包
    针对低网速的性能优化
    前端性能优化之WebP
    Openwrt自定义CGI实现
    论用户体验测试:牛逼的功能千篇一律,好的用户体验万里挑一
    Vue 依赖收集原理分析
    怎么去写好一段优雅的程序
    hdu 1085 有num1个 1 ,num2个 2 ,num3个 5 (母函数)
    hdu 1398 整数划分变形 (母函数)
    hdu 1028 整数划分 (母函数)
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/4915460.html
Copyright © 2011-2022 走看看