PTA L1-006 连续因子 (20分)

题目描述:

一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。

输入格式:

输入在一行中给出一个正整数 N(1<N<2​31​​)。

输出格式:

首先在第 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;
}
发布了109 篇原创文章 · 获赞 2 · 访问量 4593

猜你喜欢

转载自blog.csdn.net/jun_____/article/details/103964192