1. 程式人生 > >1059 Prime Factors (25 分)厄拉多塞素數篩選法

1059 Prime Factors (25 分)厄拉多塞素數篩選法

題目

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p 1 k

1 × p 2 k 2 ×
× p m k m N=p_1^{k_1} \times p_2^{k_2}\times ⋯\times p_m^{k_m}
.

Input Specification:
Each input file contains one test case which gives a positive integer N in the range of long int.

Output Specification:
Factor N N in the format N = p 1 k 1 × p 2 k 2 × × p m k m N=p_1^{k_1} \times p_2^{k_2}\times ⋯\times p_m^{k_m} ​​ , where p i p_i are prime factors of N N in increasing order, and the exponent k i k_i is the number of ​—— hence when there is only one is 1 and must NOT be printed out.

Sample Input:

97532468

Sample Output:

97532468=2^211171011291

解題思路

  題目大意: 給定一個正整數N,找到它所有的質因子,並寫成如下格式:
N = p 1 k 1 × p 2 k 2 × × p m k m N=p_1^{k_1} \times p_2^{k_2}\times ⋯\times p_m^{k_m}
  解題思路: 這道題的主要難點在找質因子上,如果用窮舉法暴力遍歷的方式去一個一個找質因子,會用到兩層迴圈,時間複雜度在 O ( n 2 ) O(n^2) ,那樣至少有兩個點會執行超時。
  這裡介紹一個更高效的找質因子的方法——厄拉多塞素數篩選法 (詳情參考連結),該方法能把N以內的質因子的篩選,時間複雜度降到 O ( n × l o g ( l o g ( n ) ) ) O(n\times log(log(n)))
  在選出所有的質因子之後就可以統計其計算係數了,可以用map直接進行統計。
  注意一個邊界點,當N自己是一個質數的時候,直接輸出自己。更特別的,當N為1時,直接輸出“1=1”。

/*
** @Brief:No.1059 of PAT advanced level.
** @Author:Jason.Lee
** @Date:2018-12-25
** @Solution: https://blog.csdn.net/CV_Jason/article/details/85282890
*/
#include<iostream>
#include<vector>
#include<map>
#define MAX 100000
using namespace std;
vector<bool> isPrime(MAX);
vector<int> prime;
int N;

void allPrime(){
	fill(isPrime.begin(),isPrime.end(),1);
	for(int i=2;i*i<MAX;i++){
		for(int j=i*i;j<MAX;j+=i){
			isPrime[j] = 0;
		}
	}
	for(int i=2;i<MAX;i++){
		if(isPrime[i]){
			prime.push_back(i);
		}
	}
} 
 
int main(){
	while(cin>>N){
		allPrime();
		map<int,int> factor;
		if(N==1){
			cout<<"1=1"<<endl;
			return 0;
		}
		int temp = N;
		while(N>1){
			for(auto elem:prime){
				while(N%elem==0){
					factor[elem]++;
					N/=elem;
				}
			}
			if(N == temp){
				cout<<N<<"="<<N<<endl;
				return 0;
			}
		}
		auto it = factor.begin();
		cout<<temp<<"="<<it->first;		
		if(it->second>1)
			cout<<"^"<<it->second;
		for(++it;it!=factor.end();it++){
			cout<<"*"<<it->first;
			if(it->second>1)
				cout<<"^"<<it->second;
		}
		cout<<endl;
	}
	return 0;
}

在這裡插入圖片描述

總結

  如果知道厄拉多塞篩選法,這道題很快就能做出來了,如果不知道,這道題近乎無解,看來有時候出了程式設計功底之外,一定的數學常識也是必備的。其實有時候覺得程式設計到底就是數學……