首先,感谢 @Daemoonn ,长时间地部分正确让人头疼……还好找到了可以AC的代码。下面的代码是稍稍改动这位大神的,也可以ac的代码。本人脑袋比较笨,所以强行加了很多注释,有误之处,希望看到这篇博文的小伙伴在评论中指出。
http://blog.csdn.net/eventqueue/article/details/51339782
#define _CRT_SECURE_NO_WARNINGS //VS2013中使用一些不安全的函数时不再警告
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
/* 2的31次方是 2147483648 13的阶乘是 6227020800 所以连续因子乘积达到2的31次方绰绰有余,但是如果要存储阶乘结果,就需要定义更长的整数 2的64次方是 18,446,744,070,000,000,000 */
const int maxn = 12;
typedef long long LongLong;//定义64位整数
int main()
{
//输入及准备
int N; //要输入的整数
scanf("%d", &N);
int lim; //循环时的上界,即N的正整数平方根
lim = sqrt(N); //获得平方根
bool flag = false; //判断是否是拥有非自身的连续因子的数,如果为false则是质数,只用输出自身
int start_of_sequence;//因子序列的开头
//计算
int length;//连续因子的长度
for (length = maxn; length >= 1; length--)//从长到短
{
for (start_of_sequence = 2; start_of_sequence <= lim; start_of_sequence++)
//猜测可能存在的因子序列
{
//用不断求阶乘的方式
LongLong ans = 1;
for (int k = start_of_sequence; k <= start_of_sequence + length - 1; k++)
//为什么是length-1呢,个人猜想主要为了适用于类似N=4的情况
{
ans *= k;
}
if (N % ans == 0)//如果该数可以被连续因子整除
{
flag = true;
break;
}
}
if (flag)//如果已经可以判断出此数有连续因子
{
break;
}
}
//输出
if (flag)//如果为含有连续因子的数
{
printf("%d\n", length);
for (int i = start_of_sequence; i <= start_of_sequence + length - 1; i++)
{
printf(i == start_of_sequence ? "%d" : "*%d", i);
}
}
else//如果为质数
{
printf("1\n%d", N);
}
puts("");
system("pause");
return 0;
}
我的解析:
这段的代码的思考,有几个值得我们去关注的地方。
首先,我们要获得最长的子序列,就要从长到短去寻找。所以在这段代码中for循环时用的–的方法
其次,start_of_sequence和length都是神奇的变量,start_of_sequence可以标定开始的位置,length标定长度,一次干两件事……个人感觉算法的魅力就在于此,充分利用资源,提高效率。
最后,区分质数和含有连续因子序列的数可以使得程序更加清晰,这样的分治还是有必要的。
我的感悟:
对于算法这个乐趣,还是慢慢来吧,个人感觉算法的学习更多的在于苦苦思索不能ac后认真地读大神们写的代码,个人感觉这样提高会很快。