L1-006 連續因子 (20分)[最詳細][包括測試點錯誤分析]

L1-006 連續因子 (20分)

題目詳情:
在這裏插入圖片描述
題目要求的結果首先得是連續因子,其次因子乘積也得是因子,輸出最長的連續因子,如果長度一樣就輸出最小的連續因子序列。

之前我沒有注意到連續因子乘積也必須是因子,所以測試點3一直通過不了。以1260舉例,它的因子有2 3 4 5 6 7 9 10 12 14 15 18 20 21 28 30 35 36…我最開始覺得是連續因子個數是6因爲2×3×4×5×6×7。但後來我意識到2×3×4×5×6×7=5040>1260,所以我又修改代碼覺得結果是5因爲2×3×4×5×6=720<1260。但我又錯了,因爲1260%720!=0即720並不是1260的因子。正確答案應該是3×4×5,因爲3、4、5首先是1260的因子,其次3、4、5連續,其次乘積也是因子即1260%(3×4×5)==0,所以答案是3和3×4×5。如果輸入6,答案應該是2和2×3。

但這個題測試可能不全,有的代碼不管輸入6的2和2×3還是1和2,提交都AC。比如你把我下面的代碼中的m+1改成m然後輸入6雖然結果是1和2,和m+1的結果2和2×3不一樣,但提交都AC,至少我寫這篇博客是系統是這樣的,說不定以後老師發現了這個bug會修改的。
在這裏插入圖片描述
輸入6,答案應該是2和2×3,也就是判斷是否因子時,m必須加1,因爲int m=sqrt(n),m是整型,整型是向下取整。雖然連續因子肯定不會以sqrt(n)+1打頭,因爲如果是素數,那只有一個因子即本身。如果不是素數,那麼肯定有一個因子在小於等於sqrt(n),如果最長序列爲1的話也是在2~sqrt(n)之中,不可能是sqrt(n)+1;如果最長序列大於1的話,更不可能是以sqrt(n)+1打頭的,因爲sqrt(n)+1乘以下一個因子必大於n。但sqrt(n)+1是有可能包括在前一個因子的序列中,就好比輸入6的這種情況。所以sqrt(n)+1還是要考慮在內的,它後面的因子就不用考慮了,肯定是不可能的,因爲不會有以它們開始的序列的。

分析結束,總之題目一定要好好理解,代碼AC後還要想想自己的思想是否全面,以防判題系統考慮不周。以下是我的AC代碼。

AC代碼:

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    int n,m,i,j,pos,sum,len,mlen=0,t=0;
    cin>>n;
    m=sqrt(n);
    int s[m];
    for(i=2; i<=m+1; i++) //連續因子相乘後還是因子,因此符合題意的因子肯定只在2~sqrt(n)+1之間
    {
        if(n%i==0)
            s[t++]=i;
    }
    if(t==0)//說明是素數
        cout<<'1'<<endl<<n<<endl;
    else if(t==1)//如果只有一個因數,那麼最長連續因子的個數爲1,最小的連續因子序列就爲s[0]
        cout<<'1'<<endl<<s[0]<<endl;
    else//大於兩個因數則進入循環
    {
        for(i=0; i<t-1; i++)
        {
            sum=s[i];
            len=1;
            for(j=i; j<t-1; j++)
            {
                if(s[j+1]-s[j]==1&&n%(sum*s[j+1])==0)//判斷是否連續  連續的話判斷相乘後是否還是因子
                {//因爲題目要求的是連續因子,既要連續,連續相乘後還得是因子
                    sum=sum*s[j+1];
                    len++;
                }
                else//不符合直接跳出,判斷以下一個因子開始的序列是否符合
                    break;
            }
            if(len>mlen)//如果長度大於最大長度則記錄開始的因子序列
            {//如果等於則不變,因爲題目要求輸出的是在序列最長的情況下輸出最小連續因子
                mlen=len;//更新最長序列
                pos=i;
            }
        }
        cout<<mlen<<endl;//按要求輸出
        cout<<s[pos];
        for(i=pos+1; i<pos+mlen; i++)
            cout<<'*'<<s[i];
        cout<<endl;
    }
    return 0;
}

運行結果:
在這裏插入圖片描述
在這裏插入圖片描述
永遠相信美好🎈

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章