ybt 1210:因子分解
OpenJudge 1.13 22:因子分解
题目中说的“素因子”就是质因数。
判断b是不是a的质因数的方法:
- 可以设质数表,遍历该质数表取出数字b,看b是不是数字a的因数。如果是,则
a /= b
。 - 也可以让b从2开始不断增大,看b是不是a的因数。如果是,则
a /= b
。
在找出一个a的因数b后,接下来的问题就是将数字a/b分解质因数。
该问题可以用迭代解决,也可以递归解决。
- 递归问题:对数字a作质因数分解,返回分解后得到的字符串
- 递归关系:找到a的一个质因数b,在分解出k个b后,
a
/
b
k
a/b^k
a/bk不再有质因数b。得到字符串
b^k*
,后面连接的字符串为对数字 a / b k a/b^k a/bk作质因数分解得到的字符串。 - 递归出口:如果数字a为1,那么返回空字符串。
先通过打表得到1~100范围内的质数表。打表方法可以借鉴:
信息学奥赛一本通 2040:【例5.7】筛选法找质数 (普通筛 线性筛)
设计数数组c,c[i]
表示质数i在数字a中作为因数出现的次数。
将数字a分解质因数的结果存在数组c中,再遍历c输出结果。
#include
using namespace std;
int main()
{
string s;
int n, k;
cin >> n;
while(n > 1)
{
for(int i = 2; i <= n; ++i)
{
if(n%i == 0)//i是n的一个质因子
{
k = 0;//k:指数
while(n%i == 0)
{
n /= i;
k++;
}
if(k == 1)
s = s + to_string(i) + "*";
else//指数大于1,写成乘方形式
s = s + to_string(i) + "^" + to_string(k) + "*";
break;
}
}
}
s.pop_back();//去掉末尾的乘号
cout << s;
return 0;
}
解法2:递归
#include
using namespace std;
string solve(int n, int f)//将数字n分解质因数,最小质因数为f,得到字符串
{
if(n == 1)
return "";
for(int i = f; i <= n; ++i)
{
if(n%i == 0)//i为n的质因数
{
int k = 0;
while(n%i == 0)
{
n /= i;
k++;
}
if(k == 1)
return to_string(i) + "*" + solve(n, i+1);
else//指数大于1,写成乘方形式
return to_string(i) + "^" + to_string(k) + "*" + solve(n, i+1);
}
}
}
int main()
{
string s;
int n, k;
cin >> n;
s = solve(n, 2);//n分解质因数,最小质因数为2
s.pop_back();//去掉末尾的乘号
cout << s;
return 0;
}
解法3:质数表+散列存储
#include
using namespace std;
#define N 30
int prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97};//通过打表得到质数表
int c[105];//c[i]:质数i出现多少次
int main()
{
string s;
int n, k, i = 2;
cin >> n;
while(i <= n)
{
if(n%i == 0)
{
n /= i;
c[i]++;//质数i出现的次数加1
}
else
i++;
}
for(int i = 2; i <= 97; ++i)
{
if(c[i] == 1)
s = s + to_string(i) + "*";
else if(c[i] > 1)
s = s + to_string(i) + "^" + to_string(c[i]) + "*";
}
s.pop_back();//去掉末尾的乘号
cout << s;
return 0;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)