C语言:L1-006 连续因子 (20 分)

一、题目

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

输入格式:

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

输出格式:

首先在第 1 行输出最长连续因子的个数;
然后在第 2 行中按 因子1 * 因子2 * …… * 因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。

输入样例:

630

输出样例:

3
567

二、方法1

1、思路

(1)易错点分析

  1. 题目要求 N( 1 < N <231),所以数据类型为 long long int。
  2. 注意这里求的是连续因子,很多人的想法就是:我把这个数的所有因子都求解出来,然后放进一个数组里,只需要判断是不是连续即可,这样有一个很严重的问题,例如
    当 N = 1680 时,其因子为 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 15, 16, 20,
    21, 24, 28, 30, 35, 40, 42, 48, 56, 60, 70, 80, 84, 105, 112, 120,
    140, 168, 210, 240, 280, 336, 420, 560, 840, 1680
    通过这组数据,我们不难发现,貌似连续因子为 2, 3, 4, 5, 6, 7, 8,但实际上我们会发现 2 * 3 * 4 * 5 * 6 * 7 * 8 = 40320 >1680,超过 1680 了。
    实际上 1680 = 2 * 3 * 4 * 5 * 7 * 2,它的连续因子仅为 2, 3, 4, 5,所以我们在计算的时候需要考虑所求连续因子的积 num <= N。
  3. 最后,我们要注意判断 N 是不是质数,如果是质数,其只有 1 和 N 两个因子,要注意同时输出(我当时就在这里犯错了)。

(2)思路

  1. 对于求一个数的因子,首先从 2 开始遍历,直到 √N 结束。
  2. 然后我们开始求连续因子,用 num 表示因子之积,count 表示连续因子的个数,从当前的数 i 开始遍历,循环继续的条件为
    N % (num * j) == 0,这个不仅仅是判断下一个数是否为因子,更重要的是可以判断 num 是否大于 N,一举两得,有效的避免的易错点 2。
  3. 最后就是需要判断 N 是否为素数。

2、代码

#include<stdio.h>
#include<math.h>
int main()
{
	long long int N, i, j, num, count, start = 0, max = 0;
	scanf("%lld", &N);
	for (i = 2; i < sqrt(N); i++)
	{
		num = 1;
		count = 0;
		for (j = i; N % (num * j) == 0; j++)
		{
			count++;
			num *= j;
		}
		if (count > max)
		{
			start = i;
			max = count;
		}
	}
	if (max == 0)
	{
		printf("1\n");
		printf("%lld\n", N);
	}
	else
	{
		printf("%lld\n", max);
		for (i = start; i < start + max - 1; i++)
		{
			printf("%lld*", i);
		}
		printf("%lld\n", i);
	}
	return 0;
}
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WE-ubytt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值