L1-006. 连续因子
https://www.patest.cn/contests/gplt/L1-006
题目地址 在上面
一个正整数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
时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
/*************************************************************************/
送你几组测试样例:
2
101
2323
720
/*************************************************************************/
这题目真心不错。 我的做法主要是 前序和的思想 + 判断素数
1. 如果 n 是素数这答案一定是 1 和 n
2. 用一个数组把 1!, 2!, 3!, 4!, ... 存起来。 然后二重循环遍历求 起始点 和 终止点。
3. 特殊的处理, 如果经过二重循环扫了一遍后( 1< n < 2^31,就是整型范围内。 20! 是接近 long long 极限的一个值, 所以我只记到了 20!), len还是 0,就说明 len 一定是 1。 假设 len > 1, 不妨令 len == 2, 就有 一奇一偶 ,偶数一定有 2 这个因子,那么 len 就不该是 0. n == 2323 == 23 * 101 (两个大于 19 的素数)
/**********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
typedef long long int ll;
#define maxn 21
ll ans[maxn], len, s, e, temp;
int n;
void init(){
ans[0] = ans[1] = 1;
for(int i=2; i<maxn; ++i)
ans[i] = ans[i-1] * i;
return ;
}
bool prime(int x){
if(x==2 || x==3 || x==5 || x==7)
return true;
if(x%2 == 0 || x==1)
return false;
int boun = (int)sqrt(x);
for(int i=3; i<=boun; i+=2){
if(x % i ==0)
return false;
}
return true;
}
int main(){
init(); // 打表
scanf("%d", &n);
if(!prime(n)) // 扫描
for(int i=2; i<maxn; ++i){
for(int j=i; j<maxn; ++j){
temp = ans[j] / ans[i] * i;
if(temp > n)
break;
if(n % temp == 0 && j-i+1 > len){
len = j-i+1;
s = i;
e = j;
}
}
}
else{ // 素数的情况
len = 1;
s = n;
e = n;
}
//特殊处理
if(len == 0){
for(int i=21; i<n; ++i){
if(prime(i) && n%i == 0){
len = 1;
s = i;
e = i;
break;
}
}
}
cout << len << endl;
for(int i=s; i<=e; ++i){
cout << i;
if(i!=e)
cout << "*";
}
cout << endl;
return 0;
}
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
typedef long long int ll;
#define maxn 21
ll ans[maxn], len, s, e, temp;
int n;
void init(){
ans[0] = ans[1] = 1;
for(int i=2; i<maxn; ++i)
ans[i] = ans[i-1] * i;
return ;
}
bool prime(int x){
if(x==2 || x==3 || x==5 || x==7)
return true;
if(x%2 == 0 || x==1)
return false;
int boun = (int)sqrt(x);
for(int i=3; i<=boun; i+=2){
if(x % i ==0)
return false;
}
return true;
}
int main(){
init(); // 打表
scanf("%d", &n);
if(!prime(n)) // 扫描
for(int i=2; i<maxn; ++i){
for(int j=i; j<maxn; ++j){
temp = ans[j] / ans[i] * i;
if(temp > n)
break;
if(n % temp == 0 && j-i+1 > len){
len = j-i+1;
s = i;
e = j;
}
}
}
else{ // 素数的情况
len = 1;
s = n;
e = n;
}
//特殊处理
if(len == 0){
for(int i=21; i<n; ++i){
if(prime(i) && n%i == 0){
len = 1;
s = i;
e = i;
break;
}
}
}
cout << len << endl;
for(int i=s; i<=e; ++i){
cout << i;
if(i!=e)
cout << "*";
}
cout << endl;
return 0;
}