L1-006 连续因子

这道题我被坑的很惨,最开始一看题,就觉得是按照从小到大的顺序找出n的所有因子,然后再找出所有因子中最长的连续子因子就好了。设dp[i]为以i结尾,它拥有多少个连续因子。运用动态转移方程:

    if(ss[i] - ss[i - 1] == 1) 

        dp[i] = dp[i - 1] + 1;

else

    dp[i] = 1;

但是我题目并没有完全弄清楚,首先n的范围过大,直接O(n)找因子要超时,必须要用O(sqrt(n))的算法;其次,输出需要是最小的连续子因子;然后我还完全没弄明白连续子因子的概念,也就是说,所有因子相乘必须能够被n整除,比如样列,5*6*7 = 210,210可以被630整除。最后还有一个bug,比如60,它的因子连续的有2,3,4,5,6,它的前面2,3,4不能组成连续因子,因为2*3*4 = 24,24不能被60整除,但是3*4*5 = 60,刚刚可以被60整除。因此它的答案为3*4*5。

最开始这些情况我没有考虑到,尤其是最后一点。后来我通过网上找代码,稍微修改一下,让它输出2到100的结果,再与我的代码的结果对比,才找出这个bug。

虽然我的代码有点丑,但还是上代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <stack>
#include <cmath>
#define maxn 1005

using namespace std;

int main()
{
    int n;
    while(cin>>n)
    {
        int m, dp[1000], ss[1000];
        dp[0] = 1;
        m = 0;
        for(int i = 2; i <= sqrt(n); i++)
            if(n % i == 0)
                ss[m++] = i;
        int ff = m;
        if(ss[m - 1] * ss[m - 1] == n)
            ff = m - 1;
        for(int i = ff - 1; i >= 0; i--)
            ss[m++] = n / ss[i];
        for(int i = 1; i < m; i++)
        {
            if(ss[i] - ss[i - 1] == 1)
            {
                long long sum = 1;
                int mm = 0;
                for(int j = 0; j < dp[i - 1] + 1; j++)   //判断连续的因子是否满足条件
                {
                    sum *= ss[i - j];
                    if(sum > n)
                    {
                        sum /= ss[i - j];
                        break;
                    }
                    mm++;                     //mm记有多少个连续因子
                }
                if(n % sum == 0)
                    dp[i] = mm;
                else
                    dp[i] = mm - 1;
            }
            else
            {
                dp[i] = 1;
            }
        }

        int re = 0, f = 0;
        for(int i = 0; i < m; i++)
        {
            if(re < dp[i])
            {
                re = dp[i];
                f = i;
            }
        }
        if(re == 0)
        {
            cout<<1<<endl<<n<<endl;

        }
        else
        {
            cout<<re<<endl;
            if(re == 1)
                cout<<ss[0]<<endl;
            else
            {
                for(int i = f - re + 1; i < f; i++)
                    cout<<ss[i]<<"*";
                cout<<ss[f]<<endl;
            }
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值