首页 > 试题广场 >

Consecutive Factors (20)

[编程题]Consecutive Factors (20)
  • 热度指数:8423 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
Among all the factors of a positive integer N, there may exist several consecutive numbers. For example, 630 can be factored as 3*5*6*7, where 5, 6, and 7 are the three consecutive numbers. Now given any positive N, you are supposed to find the maximum number of consecutive factors, and list the smallest sequence of the consecutive factors.

输入描述:
Each input file contains one test case, which gives the integer N (131).


输出描述:
For each test case, print in the first line the maximum number of consecutive factors.  Then in the second line, print the smallest sequence of the consecutive factors in the format "factor[1]*factor[2]*...*factor[k]", where the factors are listed in increasing order, and 1 is NOT included.
示例1

输入

630

输出

3
5*6*7
#include <iostream>
#include <cmath>
using namespace std;
int main(){
    long long n;
    cin>>n;
    long long sqr=(long long)sqrt(1.0*n);
    long long first=0,len=0;               //len为最长连续整数的长度,first是其中第一个
    for(long long i=2;i<=sqr;i++){         //遍历第一个整数
        long long temp=1,j;                //temp为当前连续整数的乘积
        for(j=i;;j++){
            temp*=j;
            if(n%temp!=0) break;           //j不断加1直到temp不能整除n
        }
        if(j-i>len){                       //更新最长长度与第一个整数
            len=j-i;
            first=i;
        }
    }
    if(len==0) cout<<1<<endl<<n;          //根号n范围内都无解,只能输出n本身(素数)
    else{
        cout<<len<<endl;
        for(long long i=0;i<len;i++){
            cout<<first+i;
            if(i<len-1) cout<<"*";
        }
    }
    return 0;
}

发表于 2018-02-21 23:55:10 回复(0)
这道题并不需要你求出数字的所有因数,只需要求出一个连续序列使得输入的数字能够乘除这个数列的乘积,同时要求这个连续序列的长度最长以及起始数字最小
#include <cmath>
#include <iostream>
using namespace std;

int main()
{
	int n;
	cin >> n;
	int min_start = n;
	int max_len = 1;
	int start;
	for(start=2; start <= sqrt(n); start++){
		if(n % start == 0){
			int len = 1;
			int copy_n = n, copy_start = start;
			copy_n = copy_n / start;
			start += 1;
			while(copy_n % start == 0){
				copy_n /= start;
				start ++;
				len ++;
			}
			if(len > max_len){
				max_len = len;
				start = copy_start;
				min_start = start;
			}
			else if(len == max_len && min_start > start){
				start = copy_start;
				min_start = start;
			}
		}
	}
	cout << max_len << endl;
	cout << min_start;
	for(int i=1; i<max_len; i++)
		cout << "*" << ++min_start;
	cout << endl;
	return 0;
}

发表于 2017-08-14 01:35:03 回复(0)
要从2开始遍历到sqrt(n),否则会超时。注意这里一定要取等号,即i<=sqrt(n)。不然比如n=9,sqrt(9)=3,则只能遍历一次i=2,显然不满足,还应该遍历一次i=3。最后要注意质数的情况。若最后遍历完后,存储的向量为空,应该将n作为结果输出。
#include<iostream>
(720)#include<cstdio>
#include<math.h>
(865)#include<vector>
using namespace std;
int main(){
    int num=0;
    vector<int>myVector;
    int n,up;
    cin>>n;
    for(int i=2;i<=sqrt(n);i++){
        int j=i;
        int tempN=n;
        int tempNum=0;
        vector<int>tvector;
        while(tempN%j==0){
            tempNum++;
            tempN/=j;
            tvector.push_back(j);
            j++;
        }
        if(tempNum>num){
            num=tempNum;
            myVector.clear();
            myVector.assign(tvector.begin(),tvector.end());
        }
    }
    if(myVector.empty()){
        myVector.push_back(n);
        num=1;
    }
    printf("%d\n%d",num,myVector[0]);
    for(int i=1;i<myVector.size();i++){
        printf("*%d",myVector[i]);
    }
}


发表于 2020-02-24 13:42:41 回复(0)
思路就是把申請一個List數組,每一個序列都放在一個List中,這個想法我覺得挺直观的
package NiuCode;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ConsecutiveFactors {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(bf.readLine());
        int k = 0;
        List[] sequences = new List[1001];

        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) {
                int temp = n;
                int j = i;
                sequences[k] = new ArrayList();
                sequences[k].add(j);
                temp /= j;
                j++;
                while (temp % j == 0) {
                    sequences[k].add(j);
                    temp /= j;
                    j = j + 1;
                }
                k++;
            }
        }
        int max = 0;
        int mini = -1;
        for (int i = 0; i < k; i++) {
            if (sequences[i].size() > max) {
                max = sequences[i].size();
                mini = i;
            }
        }
        if (mini != -1) {
            System.out.println(max);
            ShowArrays(sequences[mini]);
        }else {
            System.out.println(1);
            System.out.println(n);
        }
    }

    private static void ShowArrays(List sequence) {
        StringBuilder sb = new StringBuilder();
        for (Object i : sequence){
            sb.append(i+"*");
        }
        System.out.println(sb.substring(0,sb.length()-1));
    }
}


发表于 2019-12-03 20:29:14 回复(0)
解题思路:
令j作为因式链左端,i-1作为因式链右端。考察i能否进入链。
N==j*(j+1)*(j+2)*……(i-2)*(i-1)*M;
若i可整除M,则    M/=i;    N==j*(j+1)*(j+2)*……(i-2)*(i-1)*i*M;    i++;    考察下一个i。
否则,因式链左端j右移,直到i入链。
如果j右移到i-1,i仍未入链,则i不能整除N。新链从i+1开始。
萌新觉得比较短所以发来。
#include<stdio.h>
#include<math.h>

int main()
{	int i,j,k,M,N,max;
	scanf("%d",&N);
	for(i=j=2,M=N,max=0;i*i<=N;)
	{	while(j<i&&M%i)M*=j++;
		M%i?(j++):(M/=i);
		if(++i-j>max)
		{	max=i-j;
			k=j;
		}
	}
	max?printf("%d\n%d",max,k):printf("1\n%d",N);
	for(i=1;i<max;i++)printf("*%d",++k);
}


编辑于 2019-10-10 22:14:07 回复(0)
from math import sqrt
import sys
for s in sys.stdin:
    s=int(s)
    num=0
    a=[]
    for i in range(2,int(sqrt(s)+1)):
        temp=s
        n=0
        t=[]
        j=0
        p=1
        while True:
            if temp%(p*(i+j))==0:
                p*=(i+j)
                t.append(i+j)
                n+=1
                temp//(p*(i+j))
                j+=1
            else:
                break
        if n>num:
            num=n
            a=t
    cout=''
    if num>0:
        print(num)
        for i in range(num-1):
            cout+=str(a[i])
            cout+='*'
        cout+=str(a[-1])
        print(cout)
    else:
        print(1)
        print(s)

发表于 2019-09-07 15:23:13 回复(1)
//思路:看到样例输出为长度和序列值,很容易想到枚举起始值,更新记录长度。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(){
    LL n;
    scanf("%lld",&n);
    int m=sqrt(n+10),anslen=0,ansstart;
    for(int l=2;l<=m;++l){
        LL product=l;int r=l; 
        while(n%product==0){
            product*=(++r);
        }
        if(r-l>anslen)
            anslen=r-l,ansstart=l;        
    }
    if(anslen==0) printf("%d\n%lld",1,n);
    else{
        printf("%d\n",anslen);
        for(int i=0;i<anslen;++i){
            if(i==0) printf("%d",ansstart+i);
            else printf("*%d",ansstart+i);
        }
    }    
    return 0;
} 

发表于 2018-03-02 22:09:48 回复(0)
import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int limit = (int)Math.sqrt(n);
		boolean flag = true;
		int maxlen = -1;
		int s = 0;
		for(int i = 2;i<=limit;i++){
			if(n%i==0){
				flag = false;
			}
			int start = i;
			int len = 0;
			double temp = n;
			while(temp%start==0){
				len++;
				temp /= start;
				start++;
			}
			if(len>maxlen){
				maxlen = len;
				s = i;
			}
		}
		if(flag){
			System.out.println(1);
			System.out.println(n);
		}else{
			System.out.println(maxlen);
			System.out.print(s++);
			for(int i = 1;i<maxlen;i++,s++)
				System.out.print("*"+s);
			System.out.println();
		}
	}
}
编辑于 2016-07-16 16:00:57 回复(0)
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
	int N;
	while (cin >> N) {
		//初始状态假设为素数
		int min_start = N;
		int max = 1;
		int start=2;
		int sqrtn = sqrt(N);
		for (;start <= sqrtn;++start) {//只需要循环到sqrt(N),多了没必要,否则会运行超时
			if (N%start == 0) {
				//找到每一个可以被N除尽的start,然后计算连续多少个数的乘积可以被N整除
				int len = 1;
				int Ncopy = N;
				Ncopy /= start;
				while (Ncopy%(++start)==0) {//为了避免计算乘积越界,我才用了除的方式
					Ncopy /= start;
					++len;
				}
				if (len > max) {
					max = len;
					start = start - len;//每次都要重置start,从原起点开始
					min_start = start;
				}else if (len == max&&start < min_start) {//不是素数,但是只有一个数可以除尽
					start = start - len;
					min_start = start;
				}
			}
		}
		cout << max << endl;
		for (int i = 0;i < max-1;++i) {
			cout << min_start++ << "*";
		}
		cout << min_start << endl;
	}
}

发表于 2015-11-11 20:45:45 回复(0)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;

int main()
{     int n;     cin>>n;     int start_min = n, len_max = 1, start;     for(start=2;start<=sqrt(n);start++)     {         if(n%start==0)         {             int len = 1;             int x = n, t = start;             x /= start;             start++;             while(x%start == 0)             {                 x /= start;                 start++;                 len++;             }             if(len > len_max)             {                 len_max = len;                 start = t;                 start_min = start;             }else if(len==len_max && start_min>start){                 start = t;                 start_min = start;             }         }     }     cout<<len_max<<endl;     cout<<start_min;     for(int i=1;i<len_max;i++)         cout<<"*"<<start_min+i;     cout<<endl;     return 0;
}

发表于 2018-02-12 01:14:00 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) {

        int N = Integer.parseInt(getLine());
        int maxNum = 0, maxIndex = 0;
        for (int i = 2; i < Math.sqrt(N); i++) {
            int len = getLen(N, i);
            if (maxNum < len) {
                maxNum = len;
                maxIndex = i;
            }
        }
        if (maxNum == 0) System.out.println(1 + "\n" + N);
        else {
            System.out.println(maxNum);
            for (int i = 0; i < maxNum; i++) {
                if (i != maxNum - 1) System.out.print((maxIndex + i) + "*");
                else System.out.println(maxIndex + i);
            }
        }
    }

    static int getLen(int n, int x) {
        int len = 0;
        for (; n % (x + len) == 0; n = n / (x + len++)) ;
        return len;
    }

    static String getLine() {
        String line = "";
        try {
            line = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return line;
    }
}

发表于 2022-11-23 21:25:19 回复(0)
#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

int main(){
    ios::sync_with_stdio(0);
	LL n;
	cin>>n;
	LL m=(LL)sqrt(n*1.0),anslen=0,ansI=0;
	for(LL i=2;i<=m;i++){
		LL temp=1,j=i;
		while(1){
			temp*=j;
			if(n%temp!=0) break;
			if(j-i+1>anslen){
				ansI=i;
				anslen=j-i+1;
			}
			j++;
		}
	}
	if(!anslen){
		cout<<1<<endl<<n;
	}else{
		cout<<anslen<<endl;
		for(int i=0;i<anslen;i++){
			if(i>0) cout<<'*';
			cout<<ansI+i;
		}
	}
	return 0;
}

发表于 2022-11-15 21:53:24 回复(0)
#include<iostream>
#include<math.h>
using namespace std;

//题目求由n的因子构成的最长的连续串,并且连续串是最小的;例如630=3*5*6*7 ,最长连续串就是5*6*7

int main(){
    int i,j,n,sum,loc=1;
    int max_count=0;//记录最大连续长度
    cin>>n;
    /*
    我的思路:
    从2~pow(i,2)【pow(i,2)<=n】 中
    第一次循环确定连续串的开始位置
    第二次循环找满足条件的连续串
 */
    for(i=2;i<=sqrt(n)&&pow(i,max_count+1)<=n;i++){
    	//找到开始位置是i的最长的比之前的max_count还要大的连续字串
        sum=1;
        //先找到比之前的max_count多一个的连续串
        for(j=0;j<=max_count;j++){
            sum = sum*(i+j);
            if(n%sum!=0) break;
        }
        
        //找到后,如果后续很能满足条件,我接着加
        if(j==max_count+1){
            max_count++; loc=i;
            for(;pow(i+j,2)<=n;j++){
                sum = sum*(i+j);
                if(n%sum!=0) break;
                max_count++;
            }
            //i = j-1;
        }  

    }
    
    if(loc==1){
        cout<<"1\n"<<n;
        //printf("1\n%d",n); 
        return 0;
    }
    
    cout<<max_count<<endl<<loc;
    for(i=1;i<max_count;i++)
        cout<<"*"<<i+loc;
}

发表于 2021-07-28 22:00:01 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main(){
    long long num,beg;
    cin>>num;
    int ma=0;
    for(long long i=2;i<=(sqrt(num));i++){
        int k=i,now=0,tp=num;
        while(tp%k==0){
            now++;tp=tp/k;k++;
        }
        if(now>ma){
            ma=now;beg=i;
        }
    }
    if(ma){
    cout<<ma<<endl;
    for(int i=beg;i<ma+beg-1;i++)
        cout<<i<<"*";
    cout<<ma+beg-1;}
    else{
        cout<<1<<endl;
        cout<<num;
    }
}

发表于 2021-06-25 22:33:04 回复(0)
//dfs绝对会超时
//求因子数
//题目要求,先个数,再大小,因此我从小到大开始
//思路:试除法,在得到一个除数的时候,就证明这是至少有一个因子了,就可以开始了,接下来就要有更多
//     连续的因子才行,如果停止了,没有连续的因子了,就更新成最长的,从小到大保证了一定是最小
//     的连续因子。
//为了保证每个连续的因子都得到,因此需要两层循环
#include<iostream>
#include<vector>
using namespace std;

int a[2];  //由于连续,只需要存放头尾即可,这个好厉害,看别人的代码看到的
int reslen=-1;

int main(){
    int n;
    cin>>n;
    for(int i=2;i<=n/i;i++){
        if(n%i==0){
            int len=0;
            int temp=i;
            while(n%temp==0){
                len++;
                temp*=(i+len);
            }
            if(reslen<len){
                reslen=len;
                a[0]=i;
                a[1]=i+len-1;
            }
        }
    }
    if(reslen==-1){
        cout<<1<<endl;
        cout<<n;
    }
    else{
        cout<<reslen<<endl;
        for(int i=a[0];i<a[1];i++) cout<<i<<"*";
        cout<<a[1];
    }
    
    return 0;
}

发表于 2020-12-22 14:47:03 回复(0)
这个题求的是当找到某个i因子时,其下面的连续序列能否被N整除。需要注意超时问题(sqrt(N))
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;

int N;
int main()
{
	cin>>N;
	int maxN = sqrt(N);
	int tmp = 1,cnt = 0,maxcnt = 0,v=0;
	for(int i = 2;i<maxN;i++)
	{
		//找到一个因子 
		if(N%i == 0)
		{
			tmp = i;
			cnt = 1;
			for(int j = i+1;;j++)
			{
				tmp *= j;
				if(N%tmp == 0)
				{
					cnt++;
				}
				else break;//不能被整除,退出循环 	
			}
			
			if(cnt > maxcnt)
			{
				maxcnt = cnt;
				v = i;	
			} 
		}
	}
	
	//判断是否是质数
	if(maxcnt == 0) cout<<1<<endl<<N; 
	else 
	{
		cout<<maxcnt<<endl;
		for(int i=0;i<maxcnt;i++)
		{
			if(i!=maxcnt-1) cout<<v+i<<"*";
			else cout<<v+i;
		}
	}
	
	return 0;
}


发表于 2020-10-15 14:56:00 回复(0)
/*    题目大意
一个整数可能存在很多个因数组合,试在所有因数组合中找出一个最大的连续序列。
*/
int maxLen=0;    //最大序列长度
int startPoint;    //答案序列起点
int target;    

//更新最大长度以及序列起点
void upData(int index){
    int sum = 1;
    int tmpLen = 0;
    int sub = 0;
    int tmpIndex = index;
    while (true){
        sum *= tmpIndex;
        if (sum>=target || target %sum != 0) break;
        tmpLen++;
        tmpIndex++;
        if (tmpLen > maxLen) {
            startPoint = index;
            maxLen = tmpLen;
        }
    }
    return;
}

int main(){
    cin >> target;
    for (int i = 2; i <= sqrt(target); i++){
        upData(i);
    }
    if (maxLen == 0) {
        cout << 1 << "\n" << target << endl;
        return 0;
    }
    cout << maxLen << endl;
    for (int i = 0; i < maxLen; i++){
        cout << startPoint + i;
        if (i != maxLen - 1) cout << "*";
    }
    cout << endl;
    return 0;
}
/*
笔记:
第一个循环里面,遍历的最大值到平方根即可,到target/2可能导致超时
失败原因记录:
1.出现长度相同的状况:没有输出起点最小的序列组合;
2.长度为0时:应输出长度为1,序列为taget本身;
*/


编辑于 2020-02-19 21:56:40 回复(0)
我是个渣没错了。。。
最开始想到用二维vector数组 结果一直报段错误。。。我发现我好像特别喜欢用这种方式 就很容易浪费空间
还有没有考虑到一个数的因数只有1和它本身,1不用输出 但是它本身还是要输出的
#include <cstdio>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
 
 
vector<int> factor,factorend;
 
int n;
 
int main(){
    scanf("%d",&n);
     
     
    int k = 0;
    int x;
   int m = n;
    
    int max = 0;
    for(int i = 1;i <= sqrt(n);i++){
        
        m = n;
         
        for(int x = i;x <= sqrt(n);x++){
            if(m % x == 0 && x != 1){
               m = m / x;
               factor.push_back(x);
               continue;
             }  else break;
             
        }
        if(max < factor.size()){
             max = factor.size();
             factorend = factor;
             
        }
            
        factor.clear();
    }
     
    if(max == 0){
        factor.push_back(n);;
        max = factor.size();
        factorend = factor;
    }
    
    printf("%d\n",max);
    for(int i = 0;i < factorend.size();i++){
        if(i == 0){
            printf("%d",factorend[i]);
        }
        else
        printf("*%d",factorend[i]);
    }
     
     
    return 0;
}


发表于 2019-08-21 17:34:52 回复(0)
胡乱暴力,没有TLE。
直接把所有连续的因子片段求出来,然后暴力求出最长的,乘积能整除N的片段。
#include <cmath>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using LL = long long;

int main(){
    LL N;
    cin >> N;
    vector<LL> factors;
    for(int i = 2; i <= (int)(sqrt(N) + 0.5); i++){
        if(N % i == 0){
            factors.push_back(i);
            factors.push_back(N / i);
        }
    }
    factors.push_back(N);
    sort(factors.begin(), factors.end());
    vector<LL> ans;
    vector<LL> cur;
    vector<vector<LL>> segs;
    for(auto k : factors){
        if(cur.empty()){
            cur.push_back(k);
            continue;
        } 
        if(k == cur.back() + 1){
            cur.push_back(k);
        } 
        else{
            segs.push_back(vector<LL>());
            swap(segs.back(), cur);
            cur.push_back(k);
        }
    }
    segs.push_back(vector<LL>());
    swap(segs.back(), cur);
    int max_len = 0;
    for(auto& seg : segs){
        int n = seg.size();
        for(int i = 0; i < n; i++){
            for(int j = i; j < n; j++){
                LL acc = 1;
                for(int k = i; k <= j; k++){
                    acc *= seg[k];
                }
                if(N % acc == 0){
                    int len = j - i + 1;
                    if(len > max_len){
                        max_len = len;
                        ans.clear();
                        for(int k = i; k <= j; k++){
                            ans.push_back(seg[k]);
                        }
                    }
                }
            }
        }

    }
    cout << ans.size() << endl;
    for(int i = 0; i < (int)ans.size(); i++){
        if(i) cout << "*";
        cout << ans[i];
    }
    cout << endl;
}


发表于 2019-08-20 22:18:01 回复(0)
#include "stdio.h"
#include <math.h>
int main() {
    long N,n,first=2,max=0;
    scanf("%ld", &N);
    long i,j,k,x;
    x = ceil(sqrt(N))+1;
    for (i = 2; i < x; i++) {
        k = 0;
        n = N;
        for (j = i; j < x; j++) {
            if ((n%j) != 0) break;
            n = n / j;
            k++;
        }
        if (k > max) {
            max = k;
            first = i;
        }
        
    }

    
    if (max == 0) {
        max = 1;
        first = N;
    }
    printf("%ld\n", max);
    for (i=0; i < (max-1); i++) {
        printf("%ld*", first);
        first++;
    }
    printf("%ld\n", first);
    ;
}
发表于 2019-03-30 16:42:05 回复(0)