题目描述:
一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。
输入格式:
输入在一行中给出一个正整数 N(1<N<231)。
输出格式:
首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按 因子1*因子2*……*因子k
的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。
输入样例:
630
输出样例:
3
5*6*7
解题报告:
1:一开始看错题目,以为要求连续最长的连续素因子,仔细一想不对。然后才开始看懂题意,看完一直在纠结有没有不暴力的做法,想了一会,开始放弃,大力暴力。这题还是蛮有意思的,也有些难度。接下来简单说一下怎么优化到能过此题。
2:虽然暴力,但我们要明确一点,当n模上累乘等于0,这个累乘一定是答案,但不是最长的答案。
3:我们可以从累乘的长度,累乘的起始点出发暴力找答案。简单点说就是长度从1到n,累乘起始点从1到n。这样一定能找到答案。但看题目数据,妥妥的T。
4:从数据范围下手,n在整型范围内,大概21亿左右,10的10次方。那么我们可以想到最长的是从2开始一直乘,乘到刚好这个范围就是我们要遍历的累乘长度的最大值。通过代码,马上找到了12个。不放心的话写个20一定不会错=.=
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll p = pow(2, 31), ans = 1;
for(ll i=2; ;++i){
ans *= i;
if(ans >= p){
cout << "find!" << i << endl;
break;
}
}
return 0;
}
5:现在我们缩短到了12乘上10^10。但这样能过吗,1秒最多运行10^8到10^9次。也妥妥的T。
6:从开根号优化,我们知道如果n = x*x,x*(x+1)一定大于n。以x开始的长度最大就是1。循环不处理,交给最后一句处理。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fac(ll len, ll s){
ll ans = s;
for(ll i=1; i<len; ++i)ans *= (s+i);
return ans;
}
int main(){
ll n, ans = 0;
scanf("%lld", &n);
ll nn = sqrt(n);
for(ll l=12; l>=1; --l){
for(ll s=2; s<=nn; ++s){
if(n%fac(l, s)==0){
printf("%lld\n", l);
for(ll i=0; i<l; ++i)printf("%lld%s", s+i, i!=l-1?"*":"\n");
return 0;
}
}
}
printf("1\n%lld\n", n);
return 0;
}