**:
思路分析:首先可以想到以o(sqrt(n))的複雜度求出所有因子。然後排序,這樣問題就轉化為求乙個陣列的最長連續子陣列了。一開始想到的是用簡單的dp,定義dp[i]為以i結尾的最長連續子陣列的長度。
則動態規劃轉移方程為
if a[i]==a[i-1]+1 dp[i]=dp[i-1]+1;
else dp[i]=1;
這樣很容易以o(n)的複雜度求出最長的子陣列。但是提交上去卻有兩個測試樣例沒有過,除錯了好久都沒找出原因,無奈,就到網上尋找別人的ac**,發現網上都是直接暴力列舉的思路,複雜度高的一逼,應該是o(12*sqrt(n))吧,接著自己構造了一些隨機測試資料,然後用別人的ac**跑了乙份答案,再用自己的**跑了乙份答案,接著又寫了乙個判兩個檔案不一致的程式,對拍了一番,終於發現了問題所在,我這個dp算出最大子陣列長度的確沒錯,錯的是,可能這些連續的因子的乘積比該數本身還要大,舉個例子,12的因子是,2,3,4,6,12,我用dp跑出來的最大長度是3,也就是2,3,4,但是2*3*4=24了,比12本身還要大,所以是錯誤的,正確答案是2*3。其實就是dp時少了乙個條件,就是連續因子乘積要比本身小。
那知道問題出在**,問題就好解決了,只要限制下乘積就好了,考慮到因子並不多,最多1百來個,所以以o(n^2)的複雜度列舉出所有可能連續的情況也游刃有餘。
實際此演算法當然比網上別人的暴力演算法要快。
**如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long
using
namespace
std;
const
int maxn=10005;
int dp[maxn];
void debug()
bool judge(vector
a,int l,int r,int n)//判斷陣列l~r的部分是否連續,並且連續因子的乘積是否能被n整除
int main()
}sort(a.begin(),a.end());//排序所有因子
int len=1,p=0;//len 儲存最長因子,p儲存最長因子的起始位置
for(int i=0;i//列舉所有子串看是否連續
for(int j=i;jif(judge(a,i,j,n))//如連續,看是否可以更新最優解
}cout
for(int i=0;iif(f++) cout
<<"*";
cout
0;}
L1 006 連續因子
乙個正整數n的因子中可能存在若干連續的數字。例如630可以分解為3 5 6 7,其中5 6 7就是3個連續的數字。給定任一正整數n,要求編寫程式求出最長連續因子的個數,並輸出最小的連續因子序列。輸入格式 輸入在一行中給出乙個正整數n 131 輸出格式 首先在第1行輸出最長連續因子的個數 然後在第2行...
L1 006 連續因子
乙個正整數n的因子中可能存在若干連續的數字。例如630可以分解為3 5 6 7,其中5 6 7就是3個連續的數字。給定任一正整數n,要求編寫程式求出最長連續因子的個數,並輸出最小的連續因子序列。輸入格式 輸入在一行中給出乙個正整數n 131 輸出格式 首先在第1行輸出最長連續因子的個數 然後在第2行...
L1 006 連續因子
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 陳越 乙個正整數n的因子中可能存在若干連續的數字。例如630可以分解為3 5 6 7,其中5 6 7就是3個連續的數字。給定任一正整數n,要求編寫程式求出最長連續因子的個數,並輸出最小的連...