2017日照夏令營 day6 t1 fac

題目大意:
有一個與階乘有關的遊戲,給出兩個整數n ,m ,令t=n!,每輪遊戲的流程如下
1.如果 m不能整除t ,即 t mod m !=0 ,跳到第三步;如果能整除,跳到第二步
2.令t=t/m,xyx的得分+1並返回第一步
3.遊戲結束
xyx共進行T輪遊戲,他想知道每輪他的得分是多少
特別注意,m,n<10e9;

解題思路:
先理解一下題意,其實就是找n中有多少個m,可以先考慮m是質數的情況,發現在n!中,每隔m個數會出現m的倍數,我們只要不停地/m就好了。
那m是合數怎麼辦? 可以用篩法把m分解質因數,每次記錄當前質因數以及它出現的次數,然後每次算出n中有多少個當前質因數,注意因爲可能一個質因數出現多次,最後需要再/p,最後取最小值就可以了。

#include<cstdio>
#include<iostream>
using namespace std;
int T,n,m;
int ans;
int cal(int p,int a)//求n中有幾a個p
{
    int t=0;
    for (int i=n;i;i/=p) t+=i/p;
    return t/a;
}
main()
{
//  freopen("fac.in","r",stdin);
//  freopen("fac.out","w",stdout);
    cin>>T;
    while(T--)
    {
        scanf("%d%d",&n,&m);
        ans=2e9;
        for (int t,s,i=2;i*i<=m;++i)
            if (m%i==0)
            {
                t=i;s=0;
                while(m%i==0){//篩法分解質因數
                    s++;
                    m/=i;
                }
                ans=min(ans,cal(t,s));
            }
        if (m>1) ans=min(ans,cal(m,1));//因爲篩法枚舉的是小於等於根號m的質因數,如果分解後m>1,說明有且僅有一個大於根號m的質因數,特判一下。
        printf("%d\n",ans);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章