题目链接
《算法笔记》上面的代码很长也不容易理解,时间性能和空间性能都不佳,书上的参考代码如下:
#include <cstdio>
#include <cmath>
const int maxn=100010;
bool isPrime (int n){
if (n==1) return false;
int sqr=(int)sqrt(1.0 * n);
for (int i=2; i<=sqr; i++){
if (n%i==0) return false;
}
return true;
}
int prime[maxn], pNum=0;
void findPrime(){
for (int i=1; i<maxn; i++){
if (isPrime(i)){
prime[pNum++]=i;
}
}
}
struct factor{
int x,cnt;
}fac[10];
int main(){
findPrime();
int n,num=0;
scanf("%d",&n);
if (n==1) printf("1=1");
else {
printf("%d=",n);
int sqr=(int) sqrt(1.0*n);
for (int i=0; i<pNum && prime[i]<=sqr; i++){
if (n%prime[i]==0){
fac[num].x=prime[i];
fac[num].cnt=0;
while (n%prime[i]==0){
fac[num].cnt++;
n/=prime[i];
}
num++;
}
if (n==1) break;
}
if (n!=1){
fac[num].x=n;
fac[num++].cnt=1;
}
for (int i=0; i<num; i++){
if (i) printf("*");
printf("%d",fac[i].x);
if (fac[i].cnt>1){
printf("^%d",fac[i].cnt);
}
}
}
}
以下是测评结果,用时其实挺长的。
其实可以用更简单的思路来完成,我的代码:
#include <cstdio>
struct Factor{
int prime, count;
}fac[20];
int isPrime(int a){
if (a<=1) return 0;
for (int i=2; i*i<=a; i++){
if (a%i==0) return 0;
}
return 1;
}
int main(){
long long n;
scanf("%lld",&n);
if (n==1 || isPrime(n)) {
printf("%lld=%lld",n,n);
return 0;
}
printf("%lld=",n);
int num=0;
for (int i=2; i<=n; i++){
if (isPrime(i)){
if (n%i==0){
fac[num].prime=i;
fac[num].count=0;
while (n%i==0){
fac[num].count++;
n/=i;
}
num++;
}
}
if (n==1) break;
}
for (int i=0; i<num; i++){
if (i) printf("*");
if (fac[i].count>1) {
printf("%d^%d",fac[i].prime,fac[i].count);
}else {
printf("%d",fac[i].prime);
}
}
}
在时间性能上要好于参考代码,耗时是参考代码的十分之一,也能应付各种情况:
这里的 for (int i=2; i<=n; i++) 不容易想到,也挺冒险的,但节省了大量时间。