PTA之连续因子

该问题要求编写程序找出给定正整数N的所有因子中,最长的连续因子个数以及对应的最小连续因子序列。首先判断N是否为素数,然后找出所有因子,尤其关注连续的因子组合,确保其乘积能整除N。在非素数情况下,通过遍历因子并更新最大连续因子个数和起始位置来实现。
摘要由CSDN通过智能技术生成

题目:

一个正整数 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

大体思路:

先判断是不是素数,不是的话,找出所有的因数,如果连续的话,开始计数,如果计数到有因子使得之前和自己本身之积不能除以N,计数清零,从开始计数的第二个数开始计数(如1441440的因数有1,2,3,4,5,6,7,8等,但是不能同时被他们整除,所有第一种情况从1开始计数,第二种情况从3开始计数,以此类推)。如果不是因数,计数也清零。注意每次清零要保存较大的数字。

这道题本来我是想:

比如630=2*3*3*5*7,然后2,3是连续因子;5,2*3,7是连续因子,这里的6可以用比5小的数字相乘来判断是否能得到。但是有很多漏洞,比如当要两个数字相乘的时候是在一组连续因子的第一个数字,不好求。

后来纠正:1.先判断是不是质数。2.可以先把所有因子都找出来(不要以为一个数字只能用一次),来判断哪一组因子最长。

//我想如果没有数组如何储存最大的因子序列?但是没有数组的话可以存储一个数:即开始的数字,然后用for循环就好了

//看了CSDN上面定义数字用的是long long型的,结果运行超时,可以用unsigned int

//然后我有发现理解错了题目,以为只要找出因子就可以了,结果发现因子之积还要能整除N

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int isprime(int n);
int main()
{
    unsigned int N,N1;
    scanf("%d",&N);
    unsigned int i;
    unsigned int s=0,temp;
    unsigned int max=0,start;
    if(isprime(N))
        printf("1\n%d\n",N);//如果是素数,直接输出本身
    else
    {
        N1=N;
        for(i=2;i<=N/2;i++)
        {
                if(N%i==0 && N1%i==0)//如果是连续并且能整除N的因子
                {
                    N1=N1/i;
                    s=s+1;
                    if(i==N/2)
                    {
                         if(max<s)
                         {
                            temp=s;
                            max=temp;
                            start=i-temp+1;
                        }//如果因子是最大的数字,s直接和前面最长的s比较
                    }
                }
                else if(N%i==0 && N1%i!=0)//如果是因子,但是已经不能整除N了的情况
                {
                    N1=N;
                    if(max<s)
                    {
                        temp=s;
                        max=temp;
                        start=i-temp;
                    }
                    i=i-s+1;//上一段从初始的i开始计数,这一段从i+1开始计数,比如上一段从2开始,这一段从3开始。
                    s=1;//s不为0
                    continue;
                }
                else//不是因子
                {
                    N1=N;
                    if(max<s)
                    {
                        temp=s;
                        max=temp;
                        start=i-temp;
                    }//在s归零之前,比较一下s和之前最长的s
                    s=0;//不是因子,s直接归零,等到下一段再开始计算
                }
        }
        printf("%d\n",max);
        for(i=start;i<start+max-1;i++)
        printf("%d*",i);
        printf("%d",start+max-1);
    }
        return 0;
}
int isprime(int n)
{
    int i;
    for(i=2;i<=sqrt(n);i++)
    {
        if(n%i==0)
        return 0;
    }
    return 1;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值