藍橋杯 演算法訓練 素因子去重(Java)

CR_fun發表於2019-02-22

問題描述
  給定一個正整數n,求一個正整數p,滿足p僅包含n的所有素因子,且每個素因子的次數不大於1

輸入格式
  一個整數,表示n
輸出格式
  輸出一行,包含一個整數p。

樣例輸入
1000
樣例輸出
10
資料規模和約定
  n<=10^12
  樣例解釋:n=1000=2^353,p=2*5=10

分析:首先將1e6以內的素數做成一個prime[]陣列(大小為1e6,是因為n的因子中小的那一個,必定小於n的平方根),然後用n來和prime[]中的素數進行運算(具體見程式碼中),對prime[]中使用到的數求乘積,最終得到結果。
但是上面的做法不能完全正確,最後一個測試資料,個人推測,應當是一個大於1e6的素數或者是他的因子有一個是大於1e6的素數,這個時候可以在最終結果上乘上一個n即可。

還要注意資料大小,之前寫成了long n = input.nextInt(); 半天沒找到錯誤原因

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Main {

	static int[] prime = new int[80000];
	static boolean[] tmp = new boolean[1000000];
	static int primeSize = 0;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
		Scanner input = new Scanner(System.in);
		
		primeCreat();
		long n = input.nextLong();
		int index = 0;
		int ans = 1;
		int t = -1;
		for(int i=0; i<primeSize; i++) {
			if(n%prime[i]== 0) {
				while(n%prime[i] == 0) n /= prime[i];
				ans *= prime[i];
			}
		}
		ans *= n;
		System.out.println(ans);
		
	}
	
	private static void primeCreat() {
		// TODO Auto-generated method stub
		for (int i = 0; i < prime.length; i++) {
			prime[i] = 1;
		}
		for(int i=2; i<tmp.length; i++) {
			if(tmp[i]) continue;
			prime[primeSize++] = i;
			for(int j=i*2; j<tmp.length; j+=i) {
				tmp[j] = true; 
			}
		}
	}
	
}

網上看到的寫法:原理是一樣的,仔細想想的話,下面的程式碼比我的應該要高效一點。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;

public class Main {

	static int[] prime = new int[80000];
	static boolean[] tmp = new boolean[1000000];
	static int primeSize = 0;
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
		Scanner input = new Scanner(System.in);
		
		primeCreat();
		long n = input.nextLong();
		long ans = 1;
		for(int i=2; i*i < n; i++) {
			if(n%i == 0) {
				while (n%i == 0) n /= i;
				ans *= i;
			}
		}
		if(n != 1)
			ans *= n;
		System.out.println(ans);
		
	}
}

相關文章