PAT-ADVANCED1096——Consecutive Factors
阿新 • • 發佈:2018-12-20
題目描述:
題目翻譯:
1096 連續因子
在正整數N的所有因子中,可能存在幾個連續的數字。 例如,630可以被考慮為3×5×6×7,其中5,6和7是三個連續的數字。 現在給出任何正N,你應該找到連續因子的最大數量,並列出連續因子的最小序列。
輸入格式:
每個輸出檔案包含一個測試用例,其給出了一個正整數N(1 < N < 2 ^ 31)。
輸出格式:
對每個測試用例,在第一行中輸出連續因子的最大個數。在第二行中,以形式——factor[1]*factor[2]*...*factor[k],輸出連續因子的最小序列。序列中的因子以増序排列且不包括1。
輸入樣例:
630
輸出樣例:
3
5*6*7
知識點:滑動視窗法
思路:N不會被除自己以外的大於N ^ 0.5的整數整除
題目又明確指出不包括1,因此我們的左指標只需遍歷[2, N ^ 0.5)範圍內的值即可。對於每一個左指標i,如何尋找一個右指標j呢?
我們首先令j = i,再用multiply記錄當前乘積,進入以下迴圈過程:
(1)如果在j增加的過程中,使得我們的multiply >= N,break出迴圈。
(2)如果N % ((j + 1) * multiply) != 0,break出迴圈,否則更新multiply *= j + 1。
一開始我是令N % (j + 1) != 0時跳出迴圈,但這是錯誤的。如果這麼做,對於4080這個數而言,其輸出會是2 * 3 * 4 * 5 * 6,N除以這個值的餘數不是0。因為在尋找下一個值的時候,除了要保證j + 1能被N整除外,(j + 1) * multiply也要保證能被N整除才行 。而後者如果滿足,前者一定滿足,因此我們將判斷條件改為N % ((j + 1) * multiple)。
(3)令j自增1。
時間複雜度是O(N)。空間複雜度是O(1)。
C++程式碼:
#include<iostream> #include<cmath> using namespace std; int main() { int N; scanf("%d", &N); int left = 0, right = -1; //[left, right]為連續整數區間 for(int i = 2; i < sqrt(N); i++){ if(N % i != 0){ continue; } int j = i; int multiply = i; while(true){ if(multiply >= N){ break; } if(N % ((j + 1) * multiply) == 0){ multiply *= (j + 1); }else{ break; } j++; } if(j - i > right - left){ right = j; left = i; } } if(right - left + 1 == 0){ printf("1\n%d", N); return 0; } printf("%d\n", right - left + 1); for(int i = left; i <= right; i++){ printf("%d", i); if(i != right){ printf("*"); } } return 0; }
C++解題報告: