PTA L1-006 连续因子 C++实现

连续因子

一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。
输入格式:
输入在一行中给出一个正整数 N(1<N<2​31​​)。
输出格式:
首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按 因子1×因子2×……×因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。
输入样例:

630

输出样例:

3
5*6*7

Talk is cheap. Show me the code.

#include<iostream>
#include<cmath>
#include<vector>

using namespace std;
int main()
{    
	int n=0;    
	cin>>n;    
	vector<int> factors;    
	for(int i=2;i<=sqrt(n);i++)    
	{        
		int temp=1;        
		vector<int> temp_f;        
		for(int j=i;temp<=n;j++)        
		{            
			temp=temp*j;            
			if(n%temp==0)            
			{                
				temp_f.push_back(j);                
				if(temp_f.size()>factors.size())                
				{                    
					factors.assign(temp_f.begin(),temp_f.end());                
				}            
			}            
			else            
			{                
				break;            
			}        
		}    
	}    
	if(factors.size()==0)    
	{        
		cout<<1<<endl;        
		cout<<n<<endl;    
	}    
	else    
	{        
		cout<<factors.size()<<endl;        
		for(int i=0;i<factors.size();i++)        
		{                        
			cout<<factors[i];            
			if(i!=factors.size()-1)            
			{                
				cout<<"*";            
			}        
		}    
	} 
} 

解题思路

看到输入格式就下意识的联想到就一个数是否为素数的题,所以外循环中就用了sqrt()函数以防运行超时,后从网上得知平方后是不会有连续因子的,侧面也提示了我们数学知识很重要。言归正传,我们知道素数是没有因子的,所以只用输出它自己即可,长度便是1啦。对于合数来说,这道题的题目描述有可能会误导我们,我们并不需要求出正好的分解因子,例如:630 = 3 × 5 × 6 × 7,但是我们并不需要求出这4个因子,630平方以内的非1因子有2 3 5 6 7 9 10 14 15 18 21,而这些因子的乘积也必定能够被630整除,所以内循环中我们从2开始计算630%2==0可知2是因子存入vector中,630%(2×3)==0可知3也是因子也存入vector中,而630%(2×3×4)!=0可知4不是因子所以不存入vector中则break,这算一次循环,记录每次循环得到的vector的长度,如果下一次循环的vector的长度大于上一次循环的我们就进行覆盖即可。每次内循环直到乘积小于等于输入N就必须停止(因为因子乘积不可能大于N),但实际上应该也是很难到达,因为遇到不整除的乘积还是挺容易的。

分步代码解读

1.

 int n=0;    
 cin>>n;    
 vector<int> factors;    
 for(int i=2;i<=sqrt(n);i++)    
 {        
 	int temp=1;        
  	vector<int> temp_f;        
  	for(int j=i;temp<=n;j++)        
  	{            
   		temp=temp*j;            
   		if(n%temp==0)            
   		{	                
    			temp_f.push_back(j);                
    			if(temp_f.size()>factors.size())                
    			{                    
     				factors.assign(temp_f.begin(),temp_f.end());                
    			}            
   		}            
   		else            
   		{                
    			break;            
   		}        
  	}    
 }    

我们不可能一次就求得最大乘积,所以得用两层循环,外层从2开始至sqrt(N)即可停止,内层循环是求连续的因子,内层和外层肯定会重复但是并不影响,例如:外层从2开始,内层已经求得2和3都是因子,但是遇到非因子4结束时,外层仍要从3开始进入下一层内循环,但是连续因子的长度肯定是小于上次循环的(例如:上次循环的连续因子为2 3,而下次的为3,遇到4即停止了)。注意:找到更长的连续因子从而覆盖上一层时需要用assign()而不能用swap(),因为swap()是交换两个vector中的元素,而原本factors中的长度肯定是小于存着新找到的更长的连续因子的temp_f中的,会导致不能完整输出连续因子,会少一位。

2.

if(factors.size()==0)    
{        
	cout<<1<<endl;        
  	cout<<n<<endl;    
}    
else    
{        	
	cout<<factors.size()<<endl;        
  	for(int i=0;i<factors.size();i++)        
  	{                        
   		cout<<factors[i];            
   		if(i!=factors.size()-1)            
   		{                
    			cout<<"*";            
   		}        
  	}    
 } 

如果是素数直接输出长度1的本身即可,合数的话则根据vector的长度进行输出即可,注意最后一个*需要控制不能输出,否则会出现格式错误。

测试结果

在这里插入图片描述

发布了24 篇原创文章 · 获赞 1 · 访问量 228

猜你喜欢

转载自blog.csdn.net/weixin_43646424/article/details/104417795