PTIME - Prime Time题解

题目传送门(luogu)

题目传送门(SPOJ)

题目传送门(vjudge)

题目

For your math homework this week your teacher gave you five large numbers and asked you to find their prime factors. However these numbers aren't nearly large enough for someone with knowledge of programming like yourself. So you decide to take the factorial of each of these numbers. Recall that N! (N factorial) is the product of the integers from 1 through N (inclusive). It’s your job now to create a program to help you do your homework.

Input

Each test case contains a number N (2 ≤ N ≤ 10000).

Output

The output should contain a line representing the prime factorization of the factorial given number, which should be of the form: p1^e1 * p2^e2 * ... * pk^ek where p1, p2, ... pk are the distinct prime factors of the factorial of the given number in increasing order, and e1, e2, ... ek are their exponents.

Input:

10

Output:

2^8 * 3^4 * 5^2 * 7^1

中文翻译

本周你的数学作业中,老师给了你五个大数字,并要求你找到它们的质因数。然而,这些数字对像你这样有编程知识的人来说并不 够大 。于是你决定计算这些数字的阶乘。请记住,N!(N的阶乘)是从1到N(包括N)的整数的乘积。现在你的任务是创建一个程序来帮助你完成作业。

输入

每个测试用例包含一个数字N(2 ≤ N ≤ 10000)。

输出

输出应包含一行 表示给定数字的阶乘的质因数分解,形式应为: p1^e1 * p2^e2 * ... * pk^ek,其中p1, p2, ... pk是给定数字的阶乘的不同质因数,按升序排列,e1, e2, ... ek 是它们的指数。

题解

分析

这道题题目让我们求N的阶乘分解质因数

我们先从样例开始分析

样例里面n=10

10!
=10*9*8*7*6*5*4*3*2*1
=3,628,800

可以得出10!=3,628,800

分解质因数后,就是2^8 * 3^4 * 5^2 * 7^1

我们可以想到第一种方法:

先求N的阶乘,再分解质因数

但这里我们可以发现,题目中N (2 ≤ N ≤ 10000),10000!非常大,long long 会炸(10000!>9,223,372,036,854,775,807)

我们要思考一个更好的办法

有大数据的题目一般可以打表找规律

1!=1=1
2!=2=2^1
3!=3=2^1 * 3^1
4!=24=2^3 * 3^1
5!=120=2^3 * 3^1 * 5^1

打到5!时,我们会发现

1!=1=1
2!=2=1! * 2^1
3!=3=2! * 3^1
4!=24=3! * 2^2
5!=120=4! * 5^1
...

要求4!的分解质因数只需要先求出3!的分解质因数,再求出4的分解质因数,然后根据$a^n*a^m=a^{n+m}$,可以得出

3!=2^1 * 3^1
4!=2^1 * 3^1 * 2^2
  =2^3 * 3^1

就可以了

得出规律后,我们可以开始写代码了

代码

#include<bits/stdc++.h>
using namespace std;
int n;
int a[100005];//质因数的指数
int main(){
	cin>>n;
	int ii;//i分解质因数时存i的数
	for(int i=2;i<=n;i++){
		ii=i;
		for(int j=2;j<=n;j++){//分解质因数
			while(ii%j==0){
				a[j]++;ii/=j;
			}
		}
	}
	bool b=false;
	for(int i=1;i<=10000;i++){
		if (a[i]!=0){
			if (b==true){
				cout<<" * ";
			}
			cout<<i<<"^"<<a[i];
			b=true;
		}
	}
	return 0;
}

点个赞呗

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值