質因子分解

質因子分解的問題就是給定一個n使得n能夠分解爲多個因子的乘積形式,並且相同因子用指數形式表示;
例如180=2^23^25;

對於這個問題,很好理解,我們的目的就是尋找其因子,通常的方法也就是從0開始枚舉,然後通過取模或者整除操作來看是否是我們需要的元素;

具體的思路如下所示:
我們首先建立一個結構體:

struct factor{
    int  x;
    int cnt;
}fac[10];

這裏爲每一個符合條件的因子創立一個結構體,fac數組是當前該數字所有因子存儲數組;
結構體內x代表當前的因子,cnt代表當前因子出現的個數;
這裏開10的目的是如果開更大會導致int溢出,並沒有什麼必要;

接下來就是計算部分;
我們對1~sqrt(n)挨個進行枚舉;這裏借鑑了尋找判定素數的概念,因爲如果k存在,爲n的質因子,對於n/k*n來說,其也是n的質因子,我們的目的是尋找最小質因子,所以只需要枚舉到sqrt(n)就可以;

接下來要注意理解一個質因子分佈的問題;
對於我們枚舉到sqrt(n),必然會出現兩種情況:
1.所有質因子都在sqrt(n)的枚舉範圍內;
2.有一個質因子大於sqrt(n),但其餘的說有質因子都在sqrt(n)範圍內,並且該較大的質因子必爲素數;

我們該怎麼理解這個問題,第一條很好理解,顯然成立,那麼第二條必然成立嗎?
會不會有兩個數字斗大於sqrt(n),並且這兩個既可能是合數有可能是素數?

首先,不可能有兩個質因子大於sqr(n),這樣會導致乘積大於n,所以不符合初始條件;
那麼剩下的質因子一定爲素數嘛?
如果這個質因子是合數,則說明可以分解,必定可以分爲多個較小質因子的乘積,或者多個數和一個素數的乘積;
所以無論那種情況,都是兩種情況中的一個;

所以接下來我們通過枚舉,對一個質因子猛除,記錄他的出現次數,如果有餘數,進行下一個數字的枚舉猛除;直到到達sqrt(n)邊界,如果還是有餘數,則說明有第二個條件發生,有個較大的質因子,所以直接記錄,因爲這個質因子只可能出現一次,如果多次會使得乘積大於n;

大致的判斷邏輯如下所示:

for(int i=0;i<sqrt(n);i++){
        if(n%prime[i]==0){
            fac[num].x=prime[i];
            fac[num].cnt=0;
            while(n%prime[i]==0){
                fac[num].cnt++;
                n/=prime[i];
            }
            num++;
        }
    }
    if(n!=1){
            fac[num].x=n;
            fac[num++].cnt=1;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章